Compare commits

...

273 Commits
0.6.1 ... 0.7.0

Author SHA1 Message Date
43b2bf6c16 VERSION 0.7.0: fix two bugs reported on GitHub, public binaries now in the wild!
Version 0.7.0 commemorates public beta binaries now being in the wild for Mac
and Linux platforms, though this actually happened a few days ago with 0.6.14.

This version fixes two bugs. First, the Linux installer/updater now supports
both systemd and regular SysV init. It will detect which your distro uses at
install/update time and install the zerotier-one service accordingly.

Secondly, this fixes an issue that caused the service to always show ONLINE
in the GUI or 'zerotier-cli info' even if there was no net connection. The
online status should be more reliably reported now.
2014-02-14 22:22:19 -08:00
aceb938e07 Another Linux installer fix: do not clobber existing directory permissions! 2014-02-14 21:45:42 -08:00
68f44fb932 Another little Linux installer fix. 2014-02-15 00:29:32 -05:00
e38619dd02 Small fix to Linux installer. 2014-02-14 21:14:34 -08:00
4ec7cd2760 Fix for GitHub issue #38: compute whether we are ONLINE a little differently 2014-02-14 16:23:03 -08:00
b0277ab904 Clean up old init.d installation files on systemd systems if present. 2014-02-14 15:28:45 -08:00
87b26b0aaf Systemd support on Linux - GitHub issue #39 2014-02-14 15:18:59 -08:00
01d13c153d Fix compiler warnings in Linux build. 2014-02-14 13:08:54 -08:00
c17082a4f8 VERSION 0.6.14: bug fixes, Unix device persistence
This version adds persistence of *nix device names (where possible), and fixes
a possible crash in Topology.cpp that was introduced in a previous revision.

It also adds a new supernode located in Singapore!
2014-02-11 15:16:42 -08:00
9acfd3eb73 Build fix on Linux with G++. 2014-02-11 23:09:53 +00:00
0ad84b8723 Possible bug fix in Topology, have to test... 2014-02-11 15:02:21 -08:00
3f912eb4ad Fix for GitHub issue #37: remember *nix device names. 2014-02-11 14:21:59 -08:00
f1b45f7df0 A few little fixes in NodeConfig. 2014-02-11 13:20:51 -08:00
29c18d4bde Add new Singapore supernode! 2014-02-11 08:57:25 -08:00
33728840ec More local.conf stuff. 2014-02-10 16:46:53 -08:00
cd339486b7 local.conf in NodeConfig 2014-02-10 14:22:57 -08:00
e54a34d8dd Finally found a Windows installer option that doesn't cost $500 or require me to climb a huge learning curve just to do a basic software install. 2014-02-08 22:22:18 -08:00
d24b192f8c Remove old updates from updates.d on Node startup. 2014-02-07 09:13:08 -08:00
0442d7e2d6 Forgot to save solution file. 2014-02-06 23:14:41 -08:00
5b97bb247e More Windows service work... it builds! Now to do a new installer and test. Also fix a Windows compile warning in Switch.cpp. 2014-02-06 23:12:12 -08:00
8a7486577a Windows service work, remove old installer... not sure exactly what we're going to use. 2014-02-06 22:06:27 -08:00
6d17993eb6 Fix a possible infinite loop in netconf service... in the long term need to fix IP assignment logic period cause the current incarnation sucks. 2014-02-06 10:59:50 -08:00
d0e5da2884 Fix copyright notice. 2014-02-05 16:38:54 -08:00
d5b50ee466 C++ service base stuff taken from MS public domain example project and modified slightly. 2014-02-05 16:37:50 -08:00
8031fe00c7 Delete C# service... going C++, probably integrating with core. 2014-02-05 14:27:31 -08:00
3f6152806f Add security notice the first time a user joins a public network. 2014-02-05 12:38:37 -08:00
7fdca150a9 VERSION 0.6.13: small bug fix, UI work
This is just a small bug fix and some UI work. Version bumps will be
coming faster too to test auto-update.
2014-02-04 22:15:57 -08:00
165de71754 Quick start rev. 2014-02-04 22:08:42 -08:00
6b1a4b6e64 Undo last commit... 2014-02-04 17:06:50 -08:00
aaf0ef6b19 Pull static image version of quick start guide. 2014-02-04 16:31:23 -08:00
fb2745ba3b Remove another script that doesn't really belong here. 2014-02-04 14:26:09 -08:00
d452ed7db8 Fix inverted sense bug in new skip-stale-relay logic. 2014-02-03 21:15:29 -08:00
8f5cd0a361 VERSION 0.6.12: code cleanup in peers and IP address enumeration improvements
This version ties up some stuff that remains in the core before binary release.
It adds support for direct interface IP enumeration on *nix systems, as well
as a fix for IPv6 link-local addresses on OSX. This also contains some cleanup
in Peer and some improvements to help detect and route around dead or unreachable
supernodes.

Getting close!
2014-02-03 16:53:38 -08:00
d7bc3c6f4a Fix infinite loop bug introduced in last commit. 2014-02-03 12:28:23 -08:00
d04e5a1fe0 Add a simple but very nice mechanism for avoiding potentially dead supernodes. 2014-02-03 11:09:09 -08:00
bf5f09a0c7 Yank a code path it turns out we probably don't want. 2014-02-03 10:46:37 -08:00
a154d660d9 Some work on background service that runs the actual zerotier-one process. 2014-02-02 23:48:44 -08:00
7a49d50187 Windows installer work... 2014-02-02 17:38:22 -08:00
ce0bd93289 Make software update run a little more often for now. 2014-02-02 16:46:27 -08:00
0fdefdf7a4 So Linux has getifaddrs() too! Yay! 2014-02-02 02:21:09 -05:00
8236f20759 Private struct ifmaddrs for OSX cause struct ifmaddrs is missing too on OSX 10.6. 2014-02-01 23:18:31 -08:00
e16b2a8831 Real implementation of ips() on OSX, now for Linux. 2014-02-01 23:10:04 -08:00
f7fbc6f633 Remove submit script. 2014-02-01 22:31:52 -08:00
3a9b0cf132 UI quick start guide. 2014-02-01 21:55:32 -08:00
2a3e646b94 Manually generate IPv6 link-local address only on Mac. 2014-02-01 14:02:14 -08:00
64231aa3f0 Fix for GitHub issue #36 on OSX... results in a duplicate entry for IPv6 link-local but seems okay... need to test on OSX 10.6 though. 2014-01-31 15:55:45 -08:00
117e6fb356 Remove some more junk from tap driver tree. 2014-01-31 12:40:06 -08:00
03ea06fa84 VERSION 0.6.11: Windows wrap-up work, NAT-t fixes
This version fixes a minor NAT traversal issue. In the past, NAT-t links had a timeout
but otherwise were preserved. This version makes them more ephemeral and invalidates
them on sleep/wake or changes in network configuration or environment.

This is because many NAT setups are very fragile with regard to hole punches, so the
past stickiness of links caused dead links to persist too long and break connectivity
between peers.

This is about 75% of what needs to be done to greatly improve robustness. The other 25%
involves detecting failed links or failed relays.

This version is also almost done for the Windows platform, moving us even closer to
binary release.
2014-01-30 15:49:08 -08:00
525ab3faa9 Take TRACE back out of Mac makefile, fix a few decode little things. 2014-01-30 15:26:12 -08:00
490e86dde3 Bunch of fixes to startup, pinging, and choice of route. Also some TRACE updates. 2014-01-30 14:23:52 -08:00
6e076e77d8 More work on connection reset stuff... 2014-01-29 22:04:23 -08:00
d75f2f7051 SIGHUP now causes resync with peers. 2014-01-29 17:24:55 -08:00
aa1be9fcad Some TRACE cleanup. 2014-01-29 20:09:55 -05:00
17796aaed4 TRACE NOP receipt. 2014-01-29 17:08:03 -08:00
2355fa973e Tiny compiler warning fix. 2014-01-29 18:27:02 -05:00
694e9f2bdc Some cleanup and rationalization of main loop. 2014-01-29 14:09:12 -08:00
372566295e Alternate order of packet emission in unite(). 2014-01-29 12:11:01 -08:00
4e85213473 Yank RuntimeEnvironment from SysEnv. 2014-01-29 09:58:17 -08:00
d6a346ca6e Fix for GitHub issue #35 and also possibly partial fix for #29 issues. 2014-01-28 16:12:24 -08:00
8b65b3e6d7 Yank PROBE stuff since it's not used and was a premature addition to the protocol. 2014-01-28 10:41:43 -08:00
ffffc0179f Fix a couple compile items. 2014-01-27 23:16:15 -08:00
f80ec871f6 Make EthernetTap creation occur in a background thread in Network since it's a time consuming operation on Windows. This fixes one of the last remaining Windows problems. 2014-01-27 23:13:36 -08:00
e0cb5caef2 UI appearance tweaks. 2014-01-27 14:55:56 -08:00
afbbf61588 Delete persistent tap device on Windows when we leave a network. 2014-01-26 22:47:08 -08:00
28665079a0 Windows UI appearance fixes (font issue, etc.) and fix to WinSock init on GUI client. 2014-01-26 22:24:29 -08:00
80997f652b Few small cleanup things... 2014-01-26 10:59:33 -08:00
9d67a02b5f Lock down individual files in networks.d instead of directory since directory ACLs are more complex on Windows. 2014-01-26 10:32:12 -08:00
22efa1ab53 Windows Installer work, fix 100% CPU bug in EthernetTap on Windows, Windows lockDownFile() implementation that uses 'cacls' utility. 2014-01-26 10:21:43 -08:00
f19d1e253a Merge branch 'adamierymenko-dev' of ssh://shub-niggurath.zerotier.com/git/ZeroTierOne into adamierymenko-dev 2014-01-24 23:15:38 -08:00
b65f7f7895 Qt GUI now builds and runs on Windows. On Windows it can (via its manifest) automatically request admin rights on launch, which plugs it nicely into Windows' admin rights system without requiring file copies and such. 2014-01-24 23:15:14 -08:00
fb49d2ced9 Small mac installer script fix. 2014-01-24 17:30:46 -08:00
434ce96f2c Officially signed 32-bit build of Windows tap driver. 2014-01-24 17:29:46 -08:00
6ae2c5f5c7 VERSION 0.6.10: Windows runs again!
Not a significant release for OSS users, but this version marks a significant
increase in workitude on the Windows platform. A properly and officially
signed x64 driver is also included. x86 drivers and more Windows work including
Qt UI are coming soon.
2014-01-24 15:05:04 -08:00
6f4e494e06 Bunch of UI style improvements. 2014-01-24 13:26:24 -08:00
eb554a504d Fix for allIps -> ips in EthernetTap on Unix. 2014-01-23 16:25:51 -08:00
8771418170 Fix bug in tap driver introduced during unused code purge (deleted the part that acknowledges writes!), and fix bug in EthernetTap causing 0000 for etherType. Windows works now! Yay! 2014-01-23 16:10:24 -08:00
2f37ea842f Couple of Windows fixes, get rid of ips()/allIps() distinction in EthernetTap. (Will need to be fixed on Unix now... later.) 2014-01-23 14:15:00 -08:00
9232ba1da0 Tap works on Windows now, sort of. Now I discovered that Windows has two mechanisms for assigning IP addresses: the registry and lower-level calls. Joy. 2014-01-22 23:46:33 -08:00
a0916b926f Finally got the Windows x64 driver signed correctly. Turns out signtool.exe with the older (NDIS5) version of the Windows DDK does not understand cross-certificates, yet it blithely continues on and signs incorrectly anyway. Got it working by using DigiCert's own certificate tool which includes a sign files operation. Must be done manually but this doesn't have to be done often. F@!K. 2014-01-22 22:11:22 -08:00
2da6a7570b More tap driver work, increment version number, remove old binaries since signatures may not have been valid. 2014-01-22 18:38:45 -08:00
2498ecbc84 Windows compile fixes, check if running as administrator on startup for Windows. 2014-01-21 16:49:34 -08:00
4935fdf6e4 Windows ignore file updates 2014-01-21 13:18:19 -08:00
370dd6c4da Several things:
(1) Add a bunch of tedious type casts to eliminate unnecessary compiler warnings on Windows X64 builds.

(2) Some EthernetTap work to integrate Windows custom IOCTL for multicast group lookup (not done quite yet).

(3) Dump some more info in selftest to make sure our Windows path lookup functions are returning sane results.
2014-01-21 13:07:22 -08:00
06ca24e8e2 More work on Windows service, cleanup. 2014-01-21 09:18:12 -08:00
c4425c836a Ignores... 2014-01-20 17:04:44 -08:00
f0dd90d9d7 Windows Service stubs... 2014-01-20 17:03:15 -08:00
6bc5a84a2d Windows build fixes and installer work... 2014-01-20 16:16:01 -08:00
3375363d93 More tap driver cleanup, and add IOCTL to get L2 multicast ethernet address subscriptions. 2014-01-20 14:33:05 -08:00
fbb40b98ad Add Windows Build folder to ignore list. 2014-01-20 11:20:13 -08:00
a365a0e3ba Remove a lot of code that we don't need from tap-windows, further winnowing down this fork of OpenVPN's tap-windows to a more minimal version that does only basic Ethernet tap functionality. 2014-01-20 11:18:55 -08:00
45c5b66e9e Self test now passes on Windows. 2014-01-18 14:53:59 -08:00
f303c24d3c Build fix. 2014-01-18 10:23:44 -08:00
3d4762eab3 Merge branch 'adamierymenko-dev' of ssh://shub-niggurath.zerotier.com/git/ZeroTierOne into adamierymenko-dev
Conflicts:
	.gitignore
2014-01-18 10:19:53 -08:00
a5896264fa Builds on Windows now. 2014-01-18 10:17:15 -08:00
4d1cca1150 Remove VC++ warnings in C25519, also add inline to short methods. 2014-01-18 09:44:35 -08:00
092e6e947e .gitignore fixes for Windows 2014-01-17 17:11:35 -08:00
07f505971c Windows build fixes. 2014-01-17 17:09:59 -08:00
7eccc5ebf2 Windows HTTP client code (untested) 2014-01-17 16:18:21 -08:00
dab124dfb9 VERSION 0.6.9: more UI, installation, and packaging work...
Another release leading up to official binary releases... not much to the core,
but quite a bit of work on the UI, installation, and such.

This version will build and run on OSX 10.6 while previous versions would fail
due to a missing getifmaddrs() function.
2014-01-17 12:57:31 -08:00
8be664cca9 UI cleanup and license dialog. 2014-01-17 10:36:58 -08:00
866edd41a7 Build DMG from makefile for Mac. 2014-01-16 17:23:49 -08:00
412f93122d Add our own getifmaddrs() since this convenience function is not in OSX 10.6. 2014-01-16 15:11:59 -08:00
3201d1d493 mkdir fix in mac install 2014-01-16 14:14:23 -08:00
9df7f65dd5 Mac installation, and dump pre10.8 stuff because it turns out that 10.6 loads the existing kext fine. 2014-01-16 13:53:31 -08:00
e23be8c91a Get rid of make stuff for helpers that are gone. 2014-01-15 21:30:43 -08:00
99c384e110 New way of doing authenticate and install. Now with more kittens. 2014-01-15 17:00:53 -08:00
49076d406e Cheezy little helper apps: kill them with fire. There is a better way. A cleaner way. A nicer way. A way with more kittens. 2014-01-15 10:32:01 -08:00
9e491decc0 Build stuff... 2014-01-14 21:15:13 -08:00
ad77d9b014 Rebuild tap.kext on OSX 10.6 for all versions so it works on that platform. 2014-01-14 16:08:04 -08:00
4788d911ad Remove ZT1 GPL copyright from the top of code that is basically all Daniel Bernstein's 2014-01-14 08:27:59 -08:00
80ea7db9c0 Add a waiting for service message on startup to not confuse user. 2014-01-13 11:16:38 -08:00
bacb8f56c3 VERSION 0.6.8: changes in preparation for binary release
This version contains no significant changes to the engine itself, just to
the installer, the GUI, and packaging and such. It's all stuff for prep for
the big release, which is fast approaching!
2014-01-10 21:46:36 -08:00
d553555880 Add "you have not joined any networks" placeholder if networks list is empty. 2014-01-10 21:40:38 -08:00
9e508779c2 Installer AppleScript finally reinvokes the app correctly. 2014-01-10 21:26:50 -08:00
14d144ea22 UI stuff, re-launch app from AppleScript after install (still needs a bit of work) 2014-01-10 17:31:10 -08:00
305ed0b3c5 Cleanup in installer code in app. 2014-01-10 16:41:44 -08:00
9208c6b4e6 QMessageBox cleanup. 2014-01-10 16:05:54 -08:00
def893fe40 Add GPL notice to UI code. 2014-01-10 15:27:44 -08:00
2a3c9e73e5 More mac installer fixes. 2014-01-10 14:09:08 -08:00
15854a1b14 Mac installer work... 2014-01-09 22:58:31 -08:00
12a0a9dedd Update cert IDs for official build. 2014-01-09 21:15:00 -08:00
5c90afa296 Work on mac launch script, sign binary mac tap driver kext (and there was much rejoicing!) 2014-01-09 11:00:36 -08:00
68ddba60a3 Another fix to mdfind line in Mac scripts. 2014-01-08 23:35:26 -08:00
3482d836ae Mac install fixes, more internal use scripts. 2014-01-08 23:12:03 -08:00
60731e6d02 Update URLs for auto-update, check supernode version in one more place, delete pid before executing updater. 2014-01-07 16:37:36 -08:00
c1256fff5b Remove some legacy code from the core loop. 2014-01-07 15:06:02 -08:00
ddb77b1454 Make rules for internal use. 2014-01-07 14:48:56 -08:00
afec5b0f2e Official release maker... again only of academic interest to others. 2014-01-07 14:12:57 -08:00
eb1598831a Include tap.kext in mac installer. 2014-01-07 13:35:20 -08:00
ea73e736c8 Official release stuff... of only academic interest to open source third party users. 2014-01-07 13:06:34 -08:00
f2976178c9 Installer bugfix on Linux. 2014-01-06 13:25:07 -05:00
76638aae76 Linux installer builds... 2014-01-06 13:11:32 -05:00
2edaf0588a Linux installer work... 2014-01-06 12:56:00 -05:00
e525e3a571 Ready to test app-driven service install on Mac. 2014-01-05 20:59:41 -08:00
a19c19c58c Refactor SoftwareUpdate to make .nfo parse and signature check code easily reusable so it can be used from the Qt GUI code. 2014-01-05 16:24:12 -08:00
67a71868cb Install dialog in UI. 2014-01-03 22:14:30 -08:00
029f64495c Linux buildinstaller fix. 2014-01-03 16:53:55 -08:00
63d6052159 Mac installer work. 2014-01-03 16:53:00 -08:00
50043f9cd6 Remove previous installer code. 2014-01-03 16:16:21 -08:00
59b1623477 More install/deploy work for mac... 2014-01-03 15:39:09 -08:00
22b52858e0 Fix -h in zerotier-cli and move code to find auth token into LocalClient, also move auth token for mac into Mac-standard Library/Application Support location. 2014-01-03 14:03:29 -08:00
baea75f2df Installer app helper... 2014-01-03 12:15:47 -08:00
69c993357d Update mac launcher and uninstaller to use mdfind to locate app. 2014-01-03 10:26:40 -08:00
fb685bcb1d New Unix installer is script-based with a payload... no fracking idea what I will do for Windows. 2014-01-03 09:00:59 -08:00
14e4e9e479 Phasing out existing installer, delete some stuff... 2014-01-01 17:02:28 -08:00
b99940f8a1 Forget mac .pkg, we will integrate the installer into the app and have it launch it on first run. This is much more user-friendly. 2014-01-01 16:13:35 -08:00
3d76d6649f Add step to build in helpers to mac app and codesign. 2013-12-31 16:26:14 -08:00
7519d8ca2c Sign the AppleScript helper app that the UI calls to install the token file. 2013-12-31 16:20:28 -08:00
9f28eec95c VERSION 0.6.7: revert change for GitHub issue #20
This will have to be thought out more. The old version worked fine 99% of the
time so we'll revisit this.
2013-12-31 11:36:13 -08:00
17126b0c6d VERSION 0.6.6: fix to path discovery
New versions will be coming fast and furious for a bit as bugs get fixed and
testing is done in prep to the first binary release.

This version fixes a problem with WAN path discovery and a possible security
issue in PacketDecoder. (see previous comments)
2013-12-31 11:24:57 -08:00
c37cb60d3c Merge branch 'adamierymenko-dev' of shub-niggurath.zerotier.com:/git/ZeroTierOne into adamierymenko-dev 2013-12-31 14:22:05 -05:00
6c587b1c57 . 2013-12-31 11:22:54 -08:00
5917453611 Linux makefile helpful debug line. 2013-12-31 14:21:53 -05:00
cc2a1444ae TRACE output improvements and compile fix. 2013-12-31 11:18:40 -08:00
10df5dcf70 Fix several things:
(1) The changes to path learning in the two previous releases were poorly thought out,
and this version should remedy that by introducing PROBE. This is basically a kind of
ECHO request and is used to authenticate endpoints that are not learned via a valid
request/response pair. Thus we will still passively learn endpoints, but securely.

(2) Turns out there was a security oversight in _doHELLO() that could have permitted...
well... I'm not sure it was exploitable to do anything particularly interesting since
a bad identity would be discarded anyway, but fix it just the same.
2013-12-31 11:03:45 -08:00
8055635e85 VERSION 0.6.5: minor bug fix in peer connection tracking 2013-12-31 01:22:32 -08:00
83a38b8f46 VERSION 0.6.4: fixes two GitHub issues, leading up to binary release! 2013-12-30 16:52:34 -08:00
83fc684b20 Add a netconf-service version field to netconf. 2013-12-30 16:31:59 -08:00
f9d31605b8 Ethernet tap cleanup. 2013-12-29 11:10:23 -08:00
c9c093777f Move PackageMaker stuff into installfiles. 2013-12-28 20:48:13 -08:00
c33e2e5d66 Add PackageMaker doc for making OSX .pkg files. 2013-12-28 16:18:19 -08:00
a6dc4caecf Unload the mac kext on exit. 2013-12-27 21:56:02 -08:00
a5b3747c01 Linux uninstaller should remove uninstall.sh itself. 2013-12-27 21:17:00 -08:00
ec3a6428b8 Mac installation scripts fixes. 2013-12-27 15:30:39 -08:00
7a6fe203ee Rebuild OSX tap for up to 32 devices. 2013-12-27 07:41:36 -08:00
a8345b6a44 Save unsigned tap driver in pre10.8 to possibly distribute for older OSX versions that cannot load signed kexts. 2013-12-27 07:22:03 -08:00
df84bcf3bf Some logging improvements in software updater. 2013-12-27 07:13:49 -08:00
c8166b2db1 Bump version to 0.6.4 for testing, integrate software updater auto-check into PacketDecoder decode path and main loop. 2013-12-26 20:57:17 -08:00
54c2c945e0 Remove old stuff from VS projects, get driver signing working on Windows. (Just testing signing, going back to OSX and Linux now). 2013-12-26 14:46:15 -08:00
92969b4426 Fix for GitHub issue #20 (untested) 2013-12-24 10:39:29 -08:00
026442f28f docs 2013-12-22 10:56:03 -08:00
fe6b7f477c Fix for GitHub issue #30 2013-12-20 16:07:20 -08:00
434a2f7071 Yet more UI work. 2013-12-19 18:15:34 -08:00
704ee6f6c7 More UI tweaks... 2013-12-19 16:23:41 -08:00
f311be96a9 More UI cleanup... 2013-12-19 14:59:52 -08:00
191d204674 Mac uninstall script fixes. 2013-12-19 10:51:46 -08:00
4ddf97be4e More UI civic beautification. 2013-12-18 16:52:21 -08:00
a388830983 Some UI appearance improvements. 2013-12-17 18:40:01 -08:00
ea4269e0d2 Add double-click to copy IP to clipboard to UI. 2013-12-17 18:20:20 -08:00
77683eda0c Mac installer works now. 2013-12-17 15:22:39 -08:00
42ed37b385 docs 2013-12-17 12:21:57 -08:00
eadd69f843 Mac installer... almost done. 2013-12-16 22:30:37 -08:00
99213ef59a Add -fstack-protector back on Mac... turns out it does work on clang. 2013-12-16 16:56:25 -08:00
b54f998a85 Linux installer: remove old init.d files, fix for init.d startup/shutdown script. 2013-12-16 16:40:03 -08:00
b792ab8ff1 Prefer clang for Linux builds, but use gcc if no clang available. 2013-12-16 14:24:41 -08:00
27a5237462 Installer work for mac. 2013-12-13 16:55:21 -08:00
50ef47cf0a Mac launchd item and launcher script, uninstaller work. 2013-12-13 16:15:42 -08:00
8cc9692cd9 Installer work, change to plain C, work for OSX installation. 2013-12-13 13:49:46 -08:00
9ffda4f955 Update Qt build to enable building against local static libraries, rename Network to NetworkWidget to avoid filesystem or object naming collision with Network.o in node/. 2013-12-12 15:47:00 -08:00
239c9e46ea docs 2013-12-12 13:03:40 -08:00
54d1b11b19 Merge branch 'adamierymenko-dev' 2013-12-12 13:02:02 -08:00
68defd9980 VERSION 0.6.3: moving toward binary release
This version contains few changes that are visible to users building from source.

It contains an almost-complete version of the Qt-based GUI in ZeroTierUI, though
this is still a work in progress. It also contains the software update infrastructure,
which is not yet enabled by default but does basically work. Some cleanup and
dead code removal has also occurred.

The next release will probably be the first binary release with auto-update and a
full UI experience for Linux and Mac. Windows will follow later, as more work has
to be done on the Windows port.
2013-12-12 12:59:53 -08:00
f7e3c10eca Cleanup in Utils, fix for HttpClient on Linux. 2013-12-12 11:33:41 -08:00
f8be0d2961 Tell us something about auto-updates when command line help is displayed. 2013-12-12 07:50:04 -08:00
8c58635ea7 Installer builder for mac. 2013-12-11 16:31:00 -08:00
7eac53a178 Installer work... 2013-12-11 15:23:55 -08:00
ec4ffc0c2c Software update fetcher seems to work, going back to updater/installer itself. 2013-12-11 13:14:10 -08:00
a22a3ed7e8 Software update work... 2013-12-11 13:00:18 -08:00
c5ef502b42 Add check for being run as root. 2013-12-10 16:38:45 -08:00
f7f3bef313 Move some stuff to clean up root. 2013-12-10 16:17:57 -08:00
d3bcc58074 Fix update URL stuff, fix main build, add update dummy for testing updates on OSX and Linux and such. 2013-12-10 16:13:07 -08:00
bf0da9f2f7 Rest of software updater, ready to test... 2013-12-10 15:30:53 -08:00
612c17240a Dead code removal, fix for cleanup GitHub issue #28 2013-12-06 16:49:20 -08:00
b59a7cf1d8 HTTP self-test. 2013-12-06 16:27:00 -08:00
518410b7e0 HTTP client works! 2013-12-06 16:00:12 -08:00
0a0ed893c3 HTTP client work... 2013-12-06 13:15:30 -08:00
e565656865 Add -v option to get version. 2013-12-04 16:29:49 -08:00
59b26faaba Integrate idtool the same way we did with cli. 2013-12-04 14:44:28 -08:00
f5d397e8c8 Pull in-band file transfer stuff. Toyed around with that idea, but it seems that updates for some platforms are big enough and there are enough reliability concerns that just using TCP/HTTP is safer and easier. 2013-12-04 10:45:15 -08:00
66cff2e98d Create common Makefile that automatically loads make rules on a per-OS basis. 2013-12-03 14:11:43 -08:00
2133984318 Build instructions for tap-mac. 2013-12-03 13:47:13 -08:00
64bc0e4929 Exclude llvm in ext/... 2013-12-03 13:36:57 -08:00
8ffa6b2bb7 Add a flag to Mac build to eliminate an unnecessary build warning. 2013-12-03 10:46:48 -08:00
f038ed9ca2 Merge pull request #27 from gurjeet/UDP_9993_Instructions_Ubuntu_12.04
Add RUNNING.txt instructions to open UDP port 9993 on Ubuntu 12.04
2013-11-25 06:10:23 -08:00
66f627da04 Add RUNNING.txt instructions to open UDP port 9993 on Ubuntu 12.04 2013-11-21 18:28:03 -05:00
e108924060 Add script to bundle Qt frameworks with Mac .app (may not be done). 2013-11-21 17:17:39 -05:00
b699bdefbd Add shutdownIfUnreadable file feature: shut down if shutdownIfUnreadable in home folder is in fact existent but unreadable (e.g. broken link). This enables nifty shutdown on .app trashing feature for OSX. 2013-11-21 16:34:27 -05:00
74af234305 Add icons and custom Mac plist to Qt project. 2013-11-21 15:55:47 -05:00
4296db2358 Add configuration age to listnetworks results and GUI. 2013-11-21 15:11:22 -05:00
31d718c4a4 UI tweaking... 2013-11-21 14:02:08 -05:00
e3b0197e57 Network list update works in UI. 2013-11-21 13:45:44 -05:00
4d86b2f02f UI work... 2013-11-20 18:29:02 -05:00
c979a695c5 UI work, add name to listnetworks output in control bus interface. 2013-11-20 16:16:30 -05:00
902c8c38d2 UI basically works, almost ready for testing and packaging... 2013-11-20 14:10:33 -05:00
14b0639181 Set application name correctly, mac version now executes helper on startup if needed. 2013-11-20 12:19:37 -05:00
bf02c6661a UI work... 2013-11-19 15:05:14 -05:00
0adc91d6cb Add AppleScript to get authentication token and place in home directory, used for OSX GUI app to authenticate a user as authorized to admin ZT1. 2013-11-18 15:06:05 -05:00
77bab13546 More UI work, reorg Windows stuff... 2013-11-18 12:01:33 -05:00
f1b0178a85 More UI work... 2013-11-15 17:04:32 -05:00
10f03d4119 More UI work. 2013-11-15 11:09:26 -05:00
b3fdb37b87 Create UI project, start designing UI. 2013-11-13 16:50:49 -05:00
bdc0ed8065 Uninstall scripts. 2013-11-13 09:07:59 -05:00
165bc589fd Linux install and uninstall seem to work. 2013-11-08 17:37:47 -05:00
15375ef6b9 Small fix to CLI module. 2013-11-08 15:45:28 -05:00
7ec433a452 Incorporate CLI functionality into core binary with binary name aliasing to save space in updater/installer. 2013-11-08 15:23:48 -05:00
085ad9073b Linux uninstall and init script. 2013-11-08 14:32:23 -05:00
34302edcc5 Installer build script for *nix systems. 2013-11-08 11:42:11 -05:00
c93de67d79 Add netconf-service readme. 2013-11-08 09:34:17 -05:00
5179dfafbe Installer work... 2013-11-07 14:51:26 -05:00
9c4d5f8bb2 Installer... 2013-11-06 17:15:19 -05:00
f51478b470 Uninstaller scripts for *nix. 2013-11-06 15:04:05 -05:00
93427b8cb6 Installer work, add .pid file writing on *nix systems to main.cpp. 2013-11-06 14:43:47 -05:00
5d7fea2047 Delete some obsolete Windows false starts. 2013-11-06 13:35:06 -05:00
35fe5ea166 file2lz4c for making installer binaries 2013-11-06 12:06:42 -05:00
bbe5a6f5d1 Add signupdate command to idtool. 2013-11-06 11:39:07 -05:00
6b8c90bffd Upgrade LZ4, remove extraneous files, put tap-mac into ext/ to declutter root. 2013-11-06 11:01:34 -05:00
9455b1cc81 Comments, change .nfo to .sig for uploads, clean some unused code from Utils. 2013-11-06 10:38:19 -05:00
9fdec3acfc More updater work... coming along. 2013-11-05 17:08:29 -05:00
f189b9b6e9 Merge branch 'adamierymenko-dev' of shub-niggurath.zerotier.com:/git/ZeroTierOne into adamierymenko-dev 2013-11-04 17:31:12 -05:00
6c63bfce69 File transfer work, add identities for validation of updates. 2013-11-04 17:31:00 -05:00
d398c0aed2 Remove tap stuff from makefile. 2013-11-01 20:40:51 -04:00
ac4e657aaa Updater work in progress... 2013-11-01 20:39:31 -04:00
ae138566a9 Updater code, work in progress... 2013-11-01 12:38:38 -04:00
e4044eeb70 Finish stubbing out FILE_ stuff. 2013-10-28 17:25:12 -04:00
d5fdfaea56 Fix signed/unsigned compare warning. 2013-10-28 16:54:35 -04:00
d92da40bff VERSION 0.6.2: Mac users should 'sudo make install-mac-tap' again.
This version fixes a recurrent gremlin in the tap driver for Mac. If you are
having this issue, you should reinstall the tap.

If you're already running ZT1, shut it down (sudo killall zerotier-one) and
then do:

sudo kextunload /Library/Application\ Support/ZeroTier/One/tap.kext

This should unload the old version. Then type 'sudo make install-mac-tap' in
the ZT1 source home directory and the new version will be installed. ZT1 will
load the module again when it next starts.

In addition to a fix, I am now distributing tap binaries and it is no longer
built in the default Makefile. This is because Apple's in the midst of some
changes that have made building it somewhat difficult.

Another note for Mavericks users:

The first time you use ZT1, you will get a popup about unsigned kernel
extensions. This will vanish once we're out of beta and have signing keys
and signed drivers.

Other changes in this version:

 * Minor improvement to Utils::getSecureRandom
 * Bug fixes and a small change to certificates of membership for private
   networks, which now appear to be working very well!
 * Stubbed out messages for auto-update, which will be done in-band via
   the ZT1 protocol. Not implemented yet.
2013-10-28 16:32:17 -04:00
5750cf6b72 New cthulhu.zerotier.com supernode IP address. 2013-10-28 16:24:55 -04:00
7015017686 Make Makefile for Mac use clang options instead of old GCC options, and fix a nasty but obvious bug I introduced into Utils::getSecureRandom. 2013-10-28 15:53:40 -04:00
12b297a712 Put default MTU in tap back to 2800, clean up tun-related files and other things from the original pre-fork tap code base that we will never use. 2013-10-28 15:18:06 -04:00
d290306bb3 Update binary build of tap. 2013-10-28 13:23:56 -04:00
60ac1b77c5 Fix for GitHub issue #25 2013-10-28 13:22:23 -04:00
e514fe2bff Change install-mac-tap rule. 2013-10-28 09:34:36 -04:00
148619f0ba Make tap build on OSX 10.9, though not in a way that is easy for users. Instead package binaries. 2013-10-28 09:33:32 -04:00
17778a36ba Clean up secure random, add packet definitions for update distribution facility. 2013-10-27 07:26:50 -04:00
df28cd88b8 docs: we no longer use MS loopback 2013-10-26 07:39:07 -04:00
942cc0ca21 Certificate of membership works now... had to fix multicast propagation so COM is pushed with multicast, which makes tremendous sense in retrospect. 2013-10-25 14:51:55 -04:00
010616e3ae Add some more TRACE output for certs. 2013-10-25 13:43:04 -04:00
1505e8dd50 Fix netconf init and identity transfer. 2013-10-25 13:04:58 -04:00
5901972958 More tying up of certificate of membership stuff in the client. 2013-10-24 16:57:26 -04:00
bbcd76ecd0 Netconf updates -- actually issue COM, and log attempts to access networks in NetworkActivity using the new authenticated flag in the new DB schema. 2013-10-24 16:19:53 -04:00
3de76fcab1 Make network autoconf a little more frequent to tighten up expiration times. 2013-10-21 16:11:29 -04:00
d496304bbf Put back rest of selftest. 2013-10-21 15:59:22 -04:00
719dd2870d Self-test for certificate of membership. 2013-10-21 15:47:33 -04:00
281 changed files with 14760 additions and 14415 deletions

40
.gitignore vendored
View File

@ -1,30 +1,32 @@
zerotier-*
/Makefile
/ext/llvm-g++-Xcode4.6.2
/ext/llvm-g++-Xcode4.6.2.tar.bz2
/zerotier-*
/ZeroTierUI/*.user
*.o
.DS_Store
.Apple*
*.dSYM
netconf-service/netconf-test
netconf-service/netconf.service
mac-tap/tuntap/src/tap/tap
mac-tap/tuntap/tap.kext
/netconf-service/netconf-test
/netconf-service/netconf.service
/ipch
/ZeroTierOne.sdf
/ZeroTierOne.v11.suo
/vsprojects/SelfTest/Debug
/vsprojects/SelfTest/Release
/vsprojects/ZeroTierOne/Debug
/vsprojects/ZeroTierOne/Release
/vsprojects/ZeroTierOne/x64
/vsprojects/TapDriver/Win32
/vsprojects/TapDriver/x64
/vsprojects/InstallerUpdater/obj
/vsprojects/Service/obj
/Build/*
/windows/ZeroTierOne.sdf
/windows/ZeroTierOne.v11.suo
/windows/*/x64
/windows/*/Win32
/windows/ZeroTierOneService/obj
/windows/ZeroTierOneService/bin
/windows/Build
*.log
*.opensdf
*.user
*.cache
*.obj
*.tlog
/vsprojects/SelfTest/SelfTest.aps
/build-*
/ZeroTierOneInstaller-*
.qmake.stash
*.autosave
/ZeroTier One.zip
/ZeroTier One.dmg
/windows/x64
/windows/ZeroTierOneInstaller/ZeroTierOneInstaller

View File

@ -6,32 +6,40 @@ Developers note: there is currently no management of dependencies on *nix
platforms, so you should make clean ; make if you change a header. Will
do this eventually.
-- MacOS
make -f Makefile.mac
Edit Makefile.mac if you want to change between debug or release build.
-- Linux
make -f Makefile.linux
make
Edit Makefile.linux if you want to change between debug or release build.
That's it. Add ZT_AUTO_UPDATE=1 to the make command line to build an
auto-update-enabled version that will update from ZeroTier's servers.
This is disabled by default since such a build will automatically
replace itself with our binary distributions.
-- MacOS
make
The same ZT_AUTO_UPDATE=1 option as Linux supports can be used here to
build an auto-update-enabled version. By default auto-updates are not
enabled.
If you are building ext/tap-mac you will need a different version of the
OSX gcc compiler chain than what currently ships (clang). We've got a copy
available here:
http://download.zerotier.com/dev/llvm-g++-Xcode4.6.2.tar.bz2
Un-tar this into ext/ (it's excluded in .gitignore) and then 'make' in
ext/tap-mac/tuntap/src/tap.
Most users should not need to build tap-mac, since a binary is included
in ext/bin.
To build the UI you will need Qt version 5.0 or later. The Qt home must
be symbolically linked into "Qt" in the parent directory of the ZeroTier
One source tree. Then you can type "make mac-ui" and the UI should build.
You can also load the UI in Qt Creator and build/test it that way.
-- Windows
Right now Windows builds using Visual Studio 2012. Technically it should also
build with other tools, but VS2012 is what your author is using.
Load the ZeroTierOne.sln solution. Typically you won't need to worry about
any projects other than ZeroTierOne, Service, and InstallerUpdater. SelfTest
builds the selftest program which can be used to test many aspects of the
core code base. TapDriver builds the Ethernet tap driver, which shouldn't
be something end users need to do and requires a driver signing key to create
a publishable driver that users can load without big red warnings.
To just test ZeroTier One itself, build ZeroTierOne and run the binary in
an administrator-mode command window.
Instructions for doing a full build will be forthcoming once all the details
are worked out. Windows is still a work in progress.
Here be dragons.

11
Makefile Normal file
View File

@ -0,0 +1,11 @@
# Common makefile -- loads make rules for each platform
OSTYPE=$(shell uname -s)
ifeq ($(OSTYPE),Darwin)
include make-mac.mk
endif
ifeq ($(OSTYPE),Linux)
include make-linux.mk
endif

View File

@ -1,43 +0,0 @@
CC=gcc
CXX=g++
INCLUDES=
DEFS=
LIBS=
# Uncomment for a release optimized build
CFLAGS=-Wall -O3 -fno-unroll-loops -fvisibility=hidden -fstack-protector -pthread $(INCLUDES) -DNDEBUG $(DEFS)
STRIP=strip --strip-all
# Uncomment for a debug build
#CFLAGS=-Wall -g -pthread $(INCLUDES) -DZT_TRACE $(DEFS)
#STRIP=echo
# Uncomment for gprof profile build
#CFLAGS=-Wall -g -pg -pthread $(INCLUDES) $(DEFS)
#STRIP=echo
CXXFLAGS=$(CFLAGS) -fno-rtti
include objects.mk
all: one cli
one: $(OBJS)
$(CXX) $(CXXFLAGS) -o zerotier-one main.cpp $(OBJS) $(LIBS)
$(STRIP) zerotier-one
cli: $(OBJS)
$(CXX) $(CXXFLAGS) -o zerotier-cli cli.cpp $(OBJS) $(LIBS)
$(STRIP) zerotier-cli
selftest: $(OBJS)
$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.cpp $(OBJS) $(LIBS)
$(STRIP) zerotier-selftest
idtool: $(OBJS)
$(CXX) $(CXXFLAGS) -o zerotier-idtool idtool.cpp $(OBJS) $(LIBS)
$(STRIP) zerotier-idtool
clean:
rm -f $(OBJS) zerotier-*

View File

@ -1,52 +0,0 @@
CC=gcc
CXX=g++
INCLUDES=
DEFS=
LIBS=-lm
# Uncomment for a release optimized universal binary build
CFLAGS=-arch i386 -arch x86_64 -Wall -O3 -ftree-vectorize -fstack-protector -pthread -mmacosx-version-min=10.6 -DNDEBUG $(INCLUDES) $(DEFS)
STRIP=strip
# Uncomment for a debug build
#CFLAGS=-Wall -g -pthread -DZT_TRACE -DZT_LOG_STDOUT $(INCLUDES) $(DEFS)
#STRIP=echo
CXXFLAGS=$(CFLAGS) -fno-rtti
include objects.mk
all: one cli mac-tap
one: $(OBJS)
$(CXX) $(CXXFLAGS) -o zerotier-one main.cpp $(OBJS) $(LIBS)
$(STRIP) zerotier-one
cli: $(OBJS)
$(CXX) $(CXXFLAGS) -o zerotier-cli cli.cpp $(OBJS) $(LIBS)
$(STRIP) zerotier-cli
selftest: $(OBJS)
$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.cpp $(OBJS) $(LIBS)
$(STRIP) zerotier-selftest
idtool: $(OBJS)
$(CXX) $(CXXFLAGS) -o zerotier-idtool idtool.cpp $(OBJS) $(LIBS)
$(STRIP) zerotier-idtool
mac-tap: FORCE
cd mac-tap/tuntap ; make tap.kext
install-mac-tap: FORCE
mkdir -p /Library/Application\ Support/ZeroTier/One
rm -rf /Library/Application\ Support/ZeroTier/One/tap.kext
cp -R mac-tap/tuntap/tap.kext /Library/Application\ Support/ZeroTier/One
chown -R root:wheel /Library/Application\ Support/ZeroTier/One/tap.kext
clean:
rm -rf *.dSYM
rm -f $(OBJS) zerotier-*
cd mac-tap/tuntap ; make clean
FORCE:

View File

@ -7,7 +7,7 @@ By convention, ZeroTier One will keep its state here on mac:
/Library/Application Support/ZeroTier/One
ZeroTier ships with a kernel extension for its own tap device, which it
stores in the above directory. To install this from source, type:
stores in the above directory. To install this, type:
sudo make -f Makefile.mac install-mac-tap
@ -55,3 +55,24 @@ browser to see if you're online.
Port in progress, and it's going to pretty much always be more painful to
build than *nix systems. Just wait for the binary release unless you're
brave, in which case you can load the VS2012 solution and play around.
-- Open UDP port 9993
As noted in README.md, to actually function properly, you need to open
UDP port 9993 in your firewall. Following are instructions to open UDP port
9993 for specific operating systems.
--- Ubuntu (version 12.04 and possibly other versions, too)
Follow the Ubuntu documentation about UFW https://help.ubuntu.com/community/UFW
Check if your UFW is active.
sudo ufw status verbose
If it is active, open UDP port 9993
sudo ufw allow 9993/udp
You should now be able to ping and browse earth.zerotier.net

20
ZeroTierUI/Info.plist Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>CFBundleIconFile</key>
<string>zt1icon.icns</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleGetInfoString</key>
<string>ZeroTier One (Mac GUI)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleExecutable</key>
<string>ZeroTier One</string>
<key>CFBundleIdentifier</key>
<string>com.zerotier.ZeroTierOne</string>
</dict>
</plist>

BIN
ZeroTierUI/ZT1GUI.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
ZeroTierUI/ZT1GUI.xcf Normal file

Binary file not shown.

120
ZeroTierUI/ZeroTierUI.pro Normal file
View File

@ -0,0 +1,120 @@
QT += core gui widgets network
TARGET = "ZeroTier One"
TEMPLATE = app
win32:RC_FILE = ZeroTierUI.rc
win32:LIBS += winhttp.lib Iphlpapi.lib ws2_32.lib advapi32.lib Shell32.lib Rpcrt4.lib
win32:QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"
mac:ICON = zt1icon.icns
mac:QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
mac:QMAKE_INFO_PLIST = Info.plist
mac:LIBS += -framework Cocoa
SOURCES += main.cpp \
mainwindow.cpp \
aboutwindow.cpp \
../node/C25519.cpp \
../node/CertificateOfMembership.cpp \
../node/Defaults.cpp \
../node/Demarc.cpp \
../node/EthernetTap.cpp \
../node/HttpClient.cpp \
../node/Identity.cpp \
../node/InetAddress.cpp \
../node/Logger.cpp \
../node/Multicaster.cpp \
../node/Network.cpp \
../node/NetworkConfig.cpp \
../node/Node.cpp \
../node/NodeConfig.cpp \
../node/Packet.cpp \
../node/PacketDecoder.cpp \
../node/Peer.cpp \
../node/Poly1305.cpp \
../node/Salsa20.cpp \
../node/Service.cpp \
../node/SHA512.cpp \
../node/SoftwareUpdater.cpp \
../node/Switch.cpp \
../node/SysEnv.cpp \
../node/Topology.cpp \
../node/UdpSocket.cpp \
../node/Utils.cpp \
../ext/lz4/lz4.c \
../ext/lz4/lz4hc.c \
networkwidget.cpp \
installdialog.cpp \
licensedialog.cpp \
onetimedialog.cpp
HEADERS += mainwindow.h \
aboutwindow.h \
../node/Node.hpp \
../node/Utils.hpp \
../node/Defaults.hpp \
../node/Address.hpp \
../node/Array.hpp \
../node/AtomicCounter.hpp \
../node/BandwidthAccount.hpp \
../node/Buffer.hpp \
../node/C25519.hpp \
../node/CertificateOfMembership.hpp \
../node/CMWC4096.hpp \
../node/Condition.hpp \
../node/Constants.hpp \
../node/Demarc.hpp \
../node/Dictionary.hpp \
../node/EthernetTap.hpp \
../node/HttpClient.hpp \
../node/Identity.hpp \
../node/InetAddress.hpp \
../node/Logger.hpp \
../node/MAC.hpp \
../node/Multicaster.hpp \
../node/MulticastGroup.hpp \
../node/Mutex.hpp \
../node/Network.hpp \
../node/NetworkConfig.hpp \
../node/NodeConfig.hpp \
../node/NonCopyable.hpp \
../node/Packet.hpp \
../node/PacketDecoder.hpp \
../node/Peer.hpp \
../node/Poly1305.hpp \
../node/RuntimeEnvironment.hpp \
../node/Salsa20.hpp \
../node/Service.hpp \
../node/SHA512.hpp \
../node/SharedPtr.hpp \
../node/SoftwareUpdater.hpp \
../node/Switch.hpp \
../node/SysEnv.hpp \
../node/Thread.hpp \
../node/Topology.hpp \
../node/UdpSocket.hpp \
../ext/lz4/lz4.h \
../ext/lz4/lz4hc.h \
networkwidget.h \
installdialog.h \
mac_doprivileged.h \
licensedialog.h \
main.h \
onetimedialog.h
FORMS += mainwindow.ui \
aboutwindow.ui \
networkwidget.ui \
installdialog.ui \
licensedialog.ui \
quickstartdialog.ui \
onetimedialog.ui
RESOURCES += \
resources.qrc
mac:OBJECTIVE_SOURCES += \
mac_doprivileged.mm
OTHER_FILES += \
stylesheet.css

1
ZeroTierUI/ZeroTierUI.rc Normal file
View File

@ -0,0 +1 @@
IDI_ICON1 ICON DISCARDABLE "zt1icon.ico"

View File

@ -0,0 +1,48 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2012-2013 ZeroTier Networks LLC
*
* 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 <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#include "aboutwindow.h"
#include "ui_aboutwindow.h"
#include <QMessageBox>
#include <QFont>
#include "../node/Constants.hpp"
#include "../node/Node.hpp"
AboutWindow::AboutWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::AboutWindow)
{
ui->setupUi(this);
ui->aboutTextLabel->setText(QString("ZeroTier One\nVersion ")+ZeroTier::Node::versionString()+"\nQt Graphical User Interface\n\n(c)2011-2014 ZeroTier Networks LLC\n\nReleased under the terms of the GNU\nGeneral Public License v3.0, see: http://gplv3.fsf.org for terms.\n\nAuthor(s): Adam Ierymenko");
}
AboutWindow::~AboutWindow()
{
delete ui;
}

49
ZeroTierUI/aboutwindow.h Normal file
View File

@ -0,0 +1,49 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2012-2013 ZeroTier Networks LLC
*
* 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 <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#ifndef AboutWindow_H
#define AboutWindow_H
#include <QDialog>
namespace Ui {
class AboutWindow;
}
class AboutWindow : public QDialog
{
Q_OBJECT
public:
explicit AboutWindow(QWidget *parent = 0);
virtual ~AboutWindow();
private:
Ui::AboutWindow *ui;
};
#endif // AboutWindow_H

254
ZeroTierUI/aboutwindow.ui Normal file
View File

@ -0,0 +1,254 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AboutWindow</class>
<widget class="QDialog" name="AboutWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>508</width>
<height>261</height>
</rect>
</property>
<property name="windowTitle">
<string>About ZeroTier One</string>
</property>
<property name="windowIcon">
<iconset resource="resources.qrc">
<normaloff>:/img/zt1icon.png</normaloff>:/img/zt1icon.png</iconset>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="iconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="pixmap">
<pixmap resource="resources.qrc">:/img/zt1icon.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="aboutTextLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
<property name="centerButtons">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="resources.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AboutWindow</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AboutWindow</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,219 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2012-2013 ZeroTier Networks LLC
*
* 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 <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#include "installdialog.h"
#include "mainwindow.h"
#include "ui_installdialog.h"
#include "../node/Constants.hpp"
#include "../node/Defaults.hpp"
#include "../node/SoftwareUpdater.hpp"
#ifdef __UNIX_LIKE__
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#endif
#ifdef __APPLE__
#include "mac_doprivileged.h"
#endif
#include <QMainWindow>
#include <QMessageBox>
#include <QByteArray>
#include <QSslSocket>
#include <QFile>
#include <QDir>
#include <QProcess>
InstallDialog::InstallDialog(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::InstallDialog),
nam(new QNetworkAccessManager(this)),
phase(FETCHING_NFO)
{
ui->setupUi(this);
QObject::connect(nam,SIGNAL(finished(QNetworkReply*)),this,SLOT(on_networkReply(QNetworkReply*)));
const char *nfoUrl = ZeroTier::ZT_DEFAULTS.updateLatestNfoURL.c_str();
if (!*nfoUrl) {
QMessageBox::critical(this,"Download Failed","Download failed: internal error: no update URL configured in build!",QMessageBox::Ok,QMessageBox::NoButton);
QApplication::exit(1);
return;
}
QNetworkReply *reply = nam->get(QNetworkRequest(QUrl(nfoUrl)));
QObject::connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(on_downloadProgress(qint64,qint64)));
}
InstallDialog::~InstallDialog()
{
delete ui;
}
void InstallDialog::on_networkReply(QNetworkReply *reply)
{
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError) {
QMessageBox::critical(this,"Download Failed",QString("Download failed: ") + reply->errorString() + "\n\nAre you connected to the Internet?",QMessageBox::Ok,QMessageBox::NoButton);
QApplication::exit(1);
} else {
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) {
QByteArray installerData(reply->readAll());
switch(phase) {
case FETCHING_NFO: {
unsigned int vMajor = 0,vMinor = 0,vRevision = 0;
installerData.append((char)0);
const char *err = ZeroTier::SoftwareUpdater::parseNfo(installerData.data(),vMajor,vMinor,vRevision,signedBy,signature,url);
if (err) {
QMessageBox::critical(this,"Download Failed","Download failed: there is a problem with the software update web site.\nTry agian later. (invalid .nfo file)",QMessageBox::Ok,QMessageBox::NoButton);
QApplication::exit(1);
return;
}
phase = FETCHING_INSTALLER;
reply = nam->get(QNetworkRequest(QUrl(url.c_str())));
QObject::connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(on_downloadProgress(qint64,qint64)));
} break;
case FETCHING_INSTALLER: {
if (!ZeroTier::SoftwareUpdater::validateUpdate(installerData.data(),installerData.length(),signedBy,signature)) {
QMessageBox::critical(this,"Download Failed","Download failed: there is a problem with the software update web site. Try agian later. (downloaded data failed signature check)",QMessageBox::Ok,QMessageBox::NoButton);
QApplication::exit(1);
return;
}
#ifdef __APPLE__
{
std::string homePath(QDir::homePath().toStdString());
QString zt1Caches(QDir::homePath() + "/Library/Caches/ZeroTier/One");
QDir::root().mkpath(zt1Caches);
std::string instPath((zt1Caches + "/ZeroTierOneInstaller").toStdString());
std::string tmpPath((zt1Caches + "/inst.sh").toStdString());
int outfd = ::open(instPath.c_str(),O_CREAT|O_TRUNC|O_WRONLY,0755);
if (outfd <= 0) {
QMessageBox::critical(this,"Download Failed",QString("Installation failed: unable to write to ")+instPath.c_str(),QMessageBox::Ok,QMessageBox::NoButton);
QApplication::exit(1);
return;
}
if (::write(outfd,installerData.data(),installerData.length()) != installerData.length()) {
QMessageBox::critical(this,"Installation Failed",QString("Installation failed: unable to write to ")+instPath.c_str(),QMessageBox::Ok,QMessageBox::NoButton);
QApplication::exit(1);
return;
}
::close(outfd);
chmod(instPath.c_str(),0755);
FILE *scr = fopen(tmpPath.c_str(),"w");
if (!scr) {
QMessageBox::critical(this,"Installation Failed","Cannot write script to temporary Library/Caches/ZeroTier/One folder.",QMessageBox::Ok,QMessageBox::NoButton);
QApplication::exit(1);
return;
}
fprintf(scr,"#!/bin/bash\n");
fprintf(scr,"export PATH=\"/bin:/usr/bin:/sbin:/usr/sbin\"\n");
fprintf(scr,"'%s'\n",instPath.c_str());
fprintf(scr,"if [ -f '/Library/Application Support/ZeroTier/One/authtoken.secret' ]; then\n");
fprintf(scr," mkdir -p '%s/Library/Application Support/ZeroTier/One'\n",homePath.c_str());
fprintf(scr," chown %d '%s/Library/Application Support/ZeroTier'\n",(int)getuid(),homePath.c_str());
fprintf(scr," chgrp %d '%s/Library/Application Support/ZeroTier'\n",(int)getgid(),homePath.c_str());
fprintf(scr," chmod 0700 '%s/Library/Application Support/ZeroTier'\n",homePath.c_str());
fprintf(scr," chown %d '%s/Library/Application Support/ZeroTier/One'\n",(int)getuid(),homePath.c_str());
fprintf(scr," chgrp %d '%s/Library/Application Support/ZeroTier/One'\n",(int)getgid(),homePath.c_str());
fprintf(scr," chmod 0700 '%s/Library/Application Support/ZeroTier/One'\n",homePath.c_str());
fprintf(scr," cp -f '/Library/Application Support/ZeroTier/One/authtoken.secret' '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",homePath.c_str());
fprintf(scr," chown %d '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",(int)getuid(),homePath.c_str());
fprintf(scr," chgrp %d '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",(int)getgid(),homePath.c_str());
fprintf(scr," chmod 0600 '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",homePath.c_str());
fprintf(scr,"fi\n");
fprintf(scr,"exit 0\n");
fclose(scr);
chmod(tmpPath.c_str(),0755);
macExecutePrivilegedShellCommand((std::string("'")+tmpPath+"' >>/dev/null 2>&1").c_str());
unlink(tmpPath.c_str());
unlink(instPath.c_str());
// Restart the binary with whatever updates may have occurred
std::string appPath(QCoreApplication::applicationFilePath().toStdString());
execl(appPath.c_str(),appPath.c_str(),(const char *)0);
// We only make it here if execl() fails
QMessageBox::critical(this,"Re-Launch Failed","An error occurred re-launching ZeroTier One.app. Try launching it manually.",QMessageBox::Ok,QMessageBox::NoButton);
QApplication::exit(1);
return;
}
#endif
} break;
}
ui->progressBar->setMinimum(0);
ui->progressBar->setMaximum(100);
ui->progressBar->setValue(0);
} else {
QMessageBox::critical(this,"Download Failed",QString("Download failed: HTTP status code ") + reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toString(),QMessageBox::Ok,QMessageBox::NoButton);
QApplication::exit(1);
}
}
}
void InstallDialog::on_InstallDialog_rejected()
{
QApplication::exit();
}
void InstallDialog::on_cancelButton_clicked()
{
QApplication::exit();
}
void InstallDialog::on_downloadProgress(qint64 bytesReceived,qint64 bytesTotal)
{
if (bytesTotal <= 0) {
ui->progressBar->setValue(0);
ui->progressBar->setMinimum(0);
ui->progressBar->setMaximum(0);
} else {
double pct = ((double)bytesReceived / (double)bytesTotal) * 100.0;
if (pct > 100.0)
pct = 100.0;
ui->progressBar->setMinimum(0);
ui->progressBar->setMaximum(100);
ui->progressBar->setValue((int)pct);
}
}

View File

@ -0,0 +1,71 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2012-2013 ZeroTier Networks LLC
*
* 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 <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#ifndef INSTALLDIALOG_H
#define INSTALLDIALOG_H
#include <QMainWindow>
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <string>
#include "../node/Address.hpp"
namespace Ui {
class InstallDialog;
}
class InstallDialog : public QMainWindow
{
Q_OBJECT
public:
explicit InstallDialog(QWidget *parent = 0);
~InstallDialog();
private slots:
void on_networkReply(QNetworkReply *reply);
void on_InstallDialog_rejected();
void on_cancelButton_clicked();
void on_downloadProgress(qint64 bytesReceived,qint64 bytesTotal);
private:
Ui::InstallDialog *ui;
QNetworkAccessManager *nam;
enum {
FETCHING_NFO,
FETCHING_INSTALLER
} phase;
ZeroTier::Address signedBy;
std::string url,signature;
};
#endif // INSTALLDIALOG_H

124
ZeroTierUI/installdialog.ui Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>InstallDialog</class>
<widget class="QMainWindow" name="InstallDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>547</width>
<height>231</height>
</rect>
</property>
<property name="windowTitle">
<string>Install ZeroTier One Service</string>
</property>
<property name="windowIcon">
<iconset resource="resources.qrc">
<normaloff>:/img/zt1icon.png</normaloff>:/img/zt1icon.png</iconset>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Since this is your first time running ZeroTier One on this computer, the virtual Ethernet service must be downloaded and installed.
Please wait while the service downloads, then you will be prompted to enter an administrator password to install it.</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>10</number>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="maximum">
<number>0</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel and Exit</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
<resources>
<include location="resources.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,42 @@
#include <stdio.h>
#include <stdlib.h>
#include "main.h"
#include "licensedialog.h"
#include "ui_licensedialog.h"
#include "../node/Constants.hpp"
LicenseDialog::LicenseDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::LicenseDialog)
{
ui->setupUi(this);
#ifdef __WINDOWS__
QWidgetList widgets = this->findChildren<QWidget*>();
foreach(QWidget *widget, widgets) {
QFont font(widget->font());
font.setPointSizeF(font.pointSizeF() * 0.75);
widget->setFont(font);
}
#endif
}
LicenseDialog::~LicenseDialog()
{
delete ui;
}
void LicenseDialog::on_buttonBox_accepted()
{
settings->setValue("acceptedLicenseV1",true);
settings->sync();
this->setResult(QDialog::Accepted);
}
void LicenseDialog::on_buttonBox_rejected()
{
::exit(0);
}

View File

@ -0,0 +1,27 @@
#ifndef LICENSEDIALOG_H
#define LICENSEDIALOG_H
#include <QDialog>
namespace Ui {
class LicenseDialog;
}
class LicenseDialog : public QDialog
{
Q_OBJECT
public:
explicit LicenseDialog(QWidget *parent = 0);
~LicenseDialog();
private slots:
void on_buttonBox_accepted();
void on_buttonBox_rejected();
private:
Ui::LicenseDialog *ui;
};
#endif // LICENSEDIALOG_H

256
ZeroTierUI/licensedialog.ui Normal file
View File

@ -0,0 +1,256 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LicenseDialog</class>
<widget class="QDialog" name="LicenseDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>534</width>
<height>333</height>
</rect>
</property>
<property name="windowTitle">
<string>ZeroTier One</string>
</property>
<property name="windowIcon">
<iconset resource="resources.qrc">
<normaloff>:/img/zt1icon.png</normaloff>:/img/zt1icon.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>14</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Do you agree to the terms of the license agreement?</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="licenseDisplayTextEdit">
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="html">
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;title&gt;GNU General Public License v3.0 - GNU Project - Free Software Foundation (FSF)&lt;/title&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'.Lucida Grande UI'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:14px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;GNU GENERAL PUBLIC LICENSE&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Version 3, 29 June 2007 &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Copyright © 2007 Free Software Foundation, Inc. &amp;lt;&lt;a href=&quot;http://fsf.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://fsf.org/&lt;/span&gt;&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;preamble&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;P&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;reamble&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The GNU General Public License is a free, copyleft license for software and other kinds of works. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The precise terms and conditions for copying, distribution and modification follow. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;terms&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;ERMS AND CONDITIONS&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section0&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;. Definitions.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;“This License” refers to version 3 of the GNU General Public License. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;“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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;A “covered work” means either the unmodified Program or a work based on the Program. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section1&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;. Source Code.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The Corresponding Source for a work in source code form is that same work. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section2&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;. Basic Permissions.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section3&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;. Protecting Users' Legal Rights From Anti-Circumvention Law.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section4&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;. Conveying Verbatim Copies.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section5&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;. Conveying Modified Source Versions.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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: &lt;/p&gt;
&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;a) The work must carry prominent notices stating that you modified it, and giving a relevant date. &lt;/li&gt;
&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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”. &lt;/li&gt;
&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/li&gt;
&lt;li style=&quot; margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/li&gt;&lt;/ul&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section6&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;6&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;. Conveying Non-Source Forms.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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: &lt;/p&gt;
&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/li&gt;
&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/li&gt;
&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/li&gt;
&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/li&gt;
&lt;li style=&quot; margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/li&gt;&lt;/ul&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;“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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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). &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section7&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;7&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;. Additional Terms.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;“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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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: &lt;/p&gt;
&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or &lt;/li&gt;
&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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 &lt;/li&gt;
&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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 &lt;/li&gt;
&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;d) Limiting the use for publicity purposes of names of licensors or authors of the material; or &lt;/li&gt;
&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or &lt;/li&gt;
&lt;li style=&quot; margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/li&gt;&lt;/ul&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section8&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;. Termination.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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). &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section9&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;. Acceptance Not Required for Having Copies.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section10&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;0. Automatic Licensing of Downstream Recipients.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section11&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;1. Patents.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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”. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section12&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;2. No Surrender of Others' Freedom.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section13&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;3. Use with the GNU Affero General Public License.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section14&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;4. Revised Versions of this License.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section15&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;5. Disclaimer of Warranty.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section16&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;6. Limitation of Liability.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;section17&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:medium; font-weight:600;&quot;&gt;7. Interpretation of Sections 15 and 16.&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;END OF TERMS AND CONDITIONS &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;howto&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;H&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;ow to Apply These Terms to Your New Programs&lt;/span&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; &amp;lt;one line to give the program's name and a brief idea of what it does.&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; Copyright (C) &amp;lt;year&amp;gt; &amp;lt;name of author&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Courier New,courier';&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; This program is free software: you can redistribute it and/or modify&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; it under the terms of the GNU General Public License as published by&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; the Free Software Foundation, either version 3 of the License, or&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; (at your option) any later version.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Courier New,courier';&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; This program is distributed in the hope that it will be useful,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; GNU General Public License for more details.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Courier New,courier';&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; You should have received a copy of the GNU General Public License&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Also add information on how to contact you by electronic and paper mail. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; &amp;lt;program&amp;gt; Copyright (C) &amp;lt;year&amp;gt; &amp;lt;name of author&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; This is free software, and you are welcome to redistribute it&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; under certain conditions; type `show c' for details. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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”. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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 &amp;lt;&lt;a href=&quot;http://www.gnu.org/licenses/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://www.gnu.org/licenses/&lt;/span&gt;&lt;/a&gt;&amp;gt;. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;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 &amp;lt;&lt;a href=&quot;http://www.gnu.org/philosophy/why-not-lgpl.html&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://www.gnu.org/philosophy/why-not-lgpl.html&lt;/span&gt;&lt;/a&gt;&amp;gt;. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::No|QDialogButtonBox::Yes</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="resources.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>LicenseDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>LicenseDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,12 @@
#ifndef mac_doprivileged_h
#define mac_doprivileged_h
#ifdef __APPLE__
// commandAndArgs can contain only single-tic quotes and should redirect its
// stdout and stderr somewhere...
bool macExecutePrivilegedShellCommand(const char *commandAndArgs);
#endif
#endif

View File

@ -0,0 +1,24 @@
#include <string.h>
#include <stdio.h>
#include "mac_doprivileged.h"
#undef slots
#include <Cocoa/Cocoa.h>
bool macExecutePrivilegedShellCommand(const char *commandAndArgs)
{
char tmp[32768];
snprintf(tmp,sizeof(tmp),"do shell script \"%s\" with administrator privileges\n",commandAndArgs);
tmp[32767] = (char)0;
NSString *scriptApple = [[NSString alloc] initWithUTF8String:tmp];
NSAppleScript *as = [[NSAppleScript alloc] initWithSource:scriptApple];
NSDictionary *err = nil;
[as executeAndReturnError:&err];
[as release];
[scriptApple release];
return (err == nil);
}

94
ZeroTierUI/main.cpp Normal file
View File

@ -0,0 +1,94 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2012-2013 ZeroTier Networks LLC
*
* 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 <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#include "mainwindow.h"
#include "installdialog.h"
#include "licensedialog.h"
#include <QApplication>
#include <QDir>
#include <QString>
#include <QFont>
#ifdef __WINDOWS__
#include <WinSock2.h>
#include <windows.h>
#endif
QSettings *settings = (QSettings *)0;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
#ifdef __WINDOWS__
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2),&wsaData);
}
#endif
{
QFile qss(":css/stylesheet.css");
qss.open(QFile::ReadOnly);
QString style(qss.readAll());
a.setStyleSheet(style);
}
#ifdef __APPLE__
// If service isn't installed, download and install it
if (!QFile::exists("/Library/Application Support/ZeroTier/One/zerotier-one")) {
// InstallDialog is an alternative main window. It will re-launch the app
// when done.
InstallDialog id;
id.show();
return a.exec();
}
#endif
#ifdef __APPLE__
{
// Put QSettings here because this is one of the writable directories allowed
// in Apple's app store sandbox specs. We might end up in app store someday.
QString zt1AppSupport(QDir::homePath() + "/Library/Application Support/ZeroTier/One");
QDir::root().mkpath(zt1AppSupport);
settings = new QSettings(zt1AppSupport + "/ui.ini",QSettings::IniFormat);
}
#else
settings = new QSettings("ZeroTier Networks","ZeroTier One");
#endif
if (!settings->value("acceptedLicenseV1",false).toBool()) {
LicenseDialog ld;
ld.setStyleSheet(a.styleSheet());
ld.exec();
}
MainWindow w;
w.show();
return a.exec();
}

9
ZeroTierUI/main.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef MAIN_H
#define MAIN_H
#include <QSettings>
#include <QMainWindow>
extern QSettings *settings;
#endif // MAIN_H

406
ZeroTierUI/mainwindow.cpp Normal file
View File

@ -0,0 +1,406 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2012-2013 ZeroTier Networks LLC
*
* 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 <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#include <string>
#include <map>
#include <set>
#include <vector>
#include <stdexcept>
#include <utility>
#include <QClipboard>
#include <QMutex>
#include <QCoreApplication>
#include <QDir>
#include <QFile>
#include <QMessageBox>
#include <QDebug>
#include <QProcess>
#include <QStringList>
#include <QVBoxLayout>
#include <QScrollBar>
#include <QEventLoop>
#include <QFont>
#include "main.h"
#include "mainwindow.h"
#include "aboutwindow.h"
#include "networkwidget.h"
#include "ui_mainwindow.h"
#include "ui_quickstartdialog.h"
#ifdef __APPLE__
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "mac_doprivileged.h"
#endif
// Globally visible
ZeroTier::Node::LocalClient *zeroTierClient = (ZeroTier::Node::LocalClient *)0;
// Main window instance for app
QMainWindow *mainWindow = (MainWindow *)0;
// Handles message from ZeroTier One service
static void handleZTMessage(void *arg,unsigned long id,const char *line)
{
static std::map< unsigned long,std::vector<std::string> > ztReplies;
static QMutex ztReplies_m;
ztReplies_m.lock();
if (*line) {
ztReplies[id].push_back(std::string(line));
ztReplies_m.unlock();
} else { // empty lines conclude transmissions
std::map< unsigned long,std::vector<std::string> >::iterator r(ztReplies.find(id));
if (r != ztReplies.end()) {
// The message is packed into an event and sent to the main window where
// the actual parsing code lives.
MainWindow::ZTMessageEvent *event = new MainWindow::ZTMessageEvent(r->second);
ztReplies.erase(r);
ztReplies_m.unlock();
QCoreApplication::postEvent(mainWindow,event); // must post since this may be another thread
} else ztReplies_m.unlock();
}
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
pollServiceTimerId(-1)
{
mainWindow = this;
ui->setupUi(this);
if (ui->networkListWidget->verticalScrollBar())
ui->networkListWidget->verticalScrollBar()->setSingleStep(8);
#ifdef __APPLE__
QWidgetList widgets = this->findChildren<QWidget*>();
foreach(QWidget *widget, widgets)
widget->setAttribute(Qt::WA_MacShowFocusRect,false);
#endif
#ifdef __WINDOWS__
QWidgetList widgets = this->findChildren<QWidget*>();
foreach(QWidget *widget, widgets) {
QFont font(widget->font());
font.setPointSizeF(font.pointSizeF() * 0.75);
widget->setFont(font);
}
#endif
ui->noNetworksLabel->setVisible(true);
ui->noNetworksLabel->setText("Connecting to Service...");
ui->bottomContainerWidget->setVisible(false);
ui->networkListWidget->setVisible(false);
this->firstTimerTick = true;
this->pollServiceTimerId = this->startTimer(200);
this->cyclesSinceResponseFromService = 0;
}
MainWindow::~MainWindow()
{
delete ui;
delete zeroTierClient;
zeroTierClient = (ZeroTier::Node::LocalClient *)0;
mainWindow = (MainWindow *)0;
}
void MainWindow::timerEvent(QTimerEvent *event) // event can be null since code also calls this directly
{
if (this->isHidden())
return;
if (this->pollServiceTimerId < 0)
return;
if (this->firstTimerTick) {
this->firstTimerTick = false;
this->killTimer(this->pollServiceTimerId);
if (!settings->value("shown_quickStart",false).toBool()) {
on_actionQuick_Start_triggered();
settings->setValue("shown_quickStart",true);
settings->sync();
}
this->pollServiceTimerId = this->startTimer(1500);
}
if (!zeroTierClient) {
std::string authToken;
if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultUserPath().c_str(),authToken)) {
#ifdef __APPLE__
if (QFile::exists("/Library/Application Support/ZeroTier/One/zerotier-one")) {
// Authorize user by copying auth token into local home directory
QMessageBox::information(this,"Authorization Needed","Administrator privileges are required to allow the current user to control ZeroTier One on this computer. (You only have to do this once.)",QMessageBox::Ok,QMessageBox::NoButton);
std::string homePath(QDir::homePath().toStdString());
QString zt1Caches(QDir::homePath() + "/Library/Caches/ZeroTier/One");
QDir::root().mkpath(zt1Caches);
std::string tmpPath((zt1Caches + "/auth.sh").toStdString());
FILE *scr = fopen(tmpPath.c_str(),"w");
if (!scr) {
QMessageBox::critical(this,"Cannot Authorize","Unable to authorize this user to administrate ZeroTier One. (Cannot write to temporary Library/Caches/ZeroTier/One folder.)",QMessageBox::Ok,QMessageBox::NoButton);
QApplication::exit(1);
return;
}
fprintf(scr,"#!/bin/bash\n");
fprintf(scr,"export PATH=\"/bin:/usr/bin:/sbin:/usr/sbin\"\n");
fprintf(scr,"if [ -f '/Library/Application Support/ZeroTier/One/authtoken.secret' ]; then\n");
fprintf(scr," mkdir -p '%s/Library/Application Support/ZeroTier/One'\n",homePath.c_str());
fprintf(scr," chown %d '%s/Library/Application Support/ZeroTier'\n",(int)getuid(),homePath.c_str());
fprintf(scr," chgrp %d '%s/Library/Application Support/ZeroTier'\n",(int)getgid(),homePath.c_str());
fprintf(scr," chmod 0700 '%s/Library/Application Support/ZeroTier'\n",homePath.c_str());
fprintf(scr," chown %d '%s/Library/Application Support/ZeroTier/One'\n",(int)getuid(),homePath.c_str());
fprintf(scr," chgrp %d '%s/Library/Application Support/ZeroTier/One'\n",(int)getgid(),homePath.c_str());
fprintf(scr," chmod 0700 '%s/Library/Application Support/ZeroTier/One'\n",homePath.c_str());
fprintf(scr," cp -f '/Library/Application Support/ZeroTier/One/authtoken.secret' '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",homePath.c_str());
fprintf(scr," chown %d '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",(int)getuid(),homePath.c_str());
fprintf(scr," chgrp %d '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",(int)getgid(),homePath.c_str());
fprintf(scr," chmod 0600 '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",homePath.c_str());
fprintf(scr,"fi\n");
fprintf(scr,"exit 0\n");
fclose(scr);
chmod(tmpPath.c_str(),0755);
macExecutePrivilegedShellCommand((std::string("'")+tmpPath+"' >>/dev/null 2>&1").c_str());
unlink(tmpPath.c_str());
}
#endif
if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultUserPath().c_str(),authToken)) {
if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultSystemPath().c_str(),authToken)) {
QMessageBox::critical(this,"Cannot Authorize","Unable to authorize this user to administrate ZeroTier One. (Did you enter your password correctly?)",QMessageBox::Ok,QMessageBox::NoButton);
QApplication::exit(1);
return;
}
}
}
zeroTierClient = new ZeroTier::Node::LocalClient(authToken.c_str(),0,&handleZTMessage,this);
}
if (++this->cyclesSinceResponseFromService >= 3) {
if (this->cyclesSinceResponseFromService == 3)
QMessageBox::warning(this,"Service Not Running","Can't connect to the ZeroTier One service. Is it running?",QMessageBox::Ok);
ui->noNetworksLabel->setVisible(true);
ui->noNetworksLabel->setText("Connecting to Service...");
ui->bottomContainerWidget->setVisible(false);
ui->networkListWidget->setVisible(false);
}
zeroTierClient->send("info");
zeroTierClient->send("listnetworks");
zeroTierClient->send("listpeers");
}
void MainWindow::customEvent(QEvent *event)
{
ZTMessageEvent *m = (ZTMessageEvent *)event; // only one custom event type so far
if (m->ztMessage.size() == 0)
return;
this->cyclesSinceResponseFromService = 0;
std::vector<std::string> hdr(ZeroTier::Node::LocalClient::splitLine(m->ztMessage[0]));
if (hdr.size() < 2)
return;
if (hdr[0] != "200")
return;
if (hdr[1] == "info") {
if (hdr.size() >= 3)
this->myAddress = hdr[2].c_str();
if (hdr.size() >= 4)
this->myStatus = hdr[3].c_str();
if (hdr.size() >= 5)
this->myVersion = hdr[4].c_str();
} else if (hdr[1] == "listnetworks") {
std::map< std::string,std::vector<std::string> > newNetworks;
for(unsigned long i=1;i<m->ztMessage.size();++i) {
std::vector<std::string> l(ZeroTier::Node::LocalClient::splitLine(m->ztMessage[i]));
// 200 listnetworks <nwid> <name> <status> <config age> <type> <dev> <ips>
if ((l.size() == 9)&&(l[2].length() == 16))
newNetworks[l[2]] = l;
}
if (newNetworks != networks) {
networks = newNetworks;
for (bool removed=true;removed;) {
removed = false;
for(int r=0;r<ui->networkListWidget->count();++r) {
NetworkWidget *nw = (NetworkWidget *)ui->networkListWidget->itemWidget(ui->networkListWidget->item(r));
if (!networks.count(nw->networkId())) {
ui->networkListWidget->setVisible(false); // HACK to prevent an occasional crash here, discovered through hours of shotgun debugging... :P
delete ui->networkListWidget->takeItem(r);
removed = true;
break;
}
}
}
ui->networkListWidget->setVisible(true);
std::set<std::string> alreadyDisplayed;
for(int r=0;r<ui->networkListWidget->count();++r) {
NetworkWidget *nw = (NetworkWidget *)ui->networkListWidget->itemWidget(ui->networkListWidget->item(r));
if (networks.count(nw->networkId()) > 0) {
alreadyDisplayed.insert(nw->networkId());
std::vector<std::string> &l = networks[nw->networkId()];
nw->setNetworkName(l[3]);
nw->setStatus(l[4],l[5]);
nw->setNetworkType(l[6]);
nw->setNetworkDeviceName(l[7]);
nw->setIps(l[8]);
}
}
for(std::map< std::string,std::vector<std::string> >::iterator nwdata(networks.begin());nwdata!=networks.end();++nwdata) {
if (alreadyDisplayed.count(nwdata->first) == 0) {
std::vector<std::string> &l = nwdata->second;
NetworkWidget *nw = new NetworkWidget((QWidget *)0,nwdata->first);
nw->setNetworkName(l[3]);
nw->setStatus(l[4],l[5]);
nw->setNetworkType(l[6]);
nw->setNetworkDeviceName(l[7]);
nw->setIps(l[8]);
QListWidgetItem *item = new QListWidgetItem();
item->setSizeHint(nw->sizeHint());
ui->networkListWidget->addItem(item);
ui->networkListWidget->setItemWidget(item,nw);
}
}
}
} else if (hdr[1] == "listpeers") {
this->numPeers = 0;
for(unsigned long i=1;i<m->ztMessage.size();++i) {
std::vector<std::string> l(ZeroTier::Node::LocalClient::splitLine(m->ztMessage[i]));
if ((l.size() >= 5)&&((l[3] != "-")||(l[4] != "-")))
++this->numPeers; // number of direct peers online -- check for active IPv4 and/or IPv6 address
}
}
if (!ui->networkListWidget->count()) {
ui->noNetworksLabel->setText("You Have Not Joined Any Networks");
ui->noNetworksLabel->setVisible(true);
} else ui->noNetworksLabel->setVisible(false);
if (!ui->bottomContainerWidget->isVisible())
ui->bottomContainerWidget->setVisible(true);
if (!ui->networkListWidget->isVisible())
ui->networkListWidget->setVisible(true);
if (this->myAddress.size())
ui->addressButton->setText(this->myAddress);
else ui->addressButton->setText(" ");
QString st(this->myStatus);
st += ", v";
st += this->myVersion;
st += ", ";
st += QString::number(this->numPeers);
st += " direct links to peers";
ui->statusLabel->setText(st);
}
void MainWindow::on_joinNetworkButton_clicked()
{
QString toJoin(ui->networkIdLineEdit->text());
ui->networkIdLineEdit->setText(QString());
if (!zeroTierClient) // sanity check
return;
if (toJoin.size() != 16) {
QMessageBox::information(this,"Invalid Network ID","The network ID you entered was not valid. Enter a 16-digit hexadecimal network ID, like '8056c2e21c000001'.",QMessageBox::Ok,QMessageBox::NoButton);
return;
}
zeroTierClient->send((QString("join ") + toJoin).toStdString());
}
void MainWindow::on_actionAbout_triggered()
{
AboutWindow *about = new AboutWindow(this);
about->show();
}
void MainWindow::on_networkIdLineEdit_textChanged(const QString &text)
{
QString newText;
for(QString::const_iterator i(text.begin());i!=text.end();++i) {
switch(i->toLatin1()) {
case '0': newText.append('0'); break;
case '1': newText.append('1'); break;
case '2': newText.append('2'); break;
case '3': newText.append('3'); break;
case '4': newText.append('4'); break;
case '5': newText.append('5'); break;
case '6': newText.append('6'); break;
case '7': newText.append('7'); break;
case '8': newText.append('8'); break;
case '9': newText.append('9'); break;
case 'a': newText.append('a'); break;
case 'b': newText.append('b'); break;
case 'c': newText.append('c'); break;
case 'd': newText.append('d'); break;
case 'e': newText.append('e'); break;
case 'f': newText.append('f'); break;
case 'A': newText.append('a'); break;
case 'B': newText.append('b'); break;
case 'C': newText.append('c'); break;
case 'D': newText.append('d'); break;
case 'E': newText.append('e'); break;
case 'F': newText.append('f'); break;
default: break;
}
}
if (newText.size() > 16)
newText.truncate(16);
ui->networkIdLineEdit->setText(newText);
}
void MainWindow::on_addressButton_clicked()
{
QApplication::clipboard()->setText(this->myAddress);
}
void MainWindow::on_actionQuick_Start_triggered()
{
Ui::QuickstartDialog qd;
QDialog *qdd = new QDialog(this);
qd.setupUi(qdd);
qdd->setModal(false);
qdd->show();
}

100
ZeroTierUI/mainwindow.h Normal file
View File

@ -0,0 +1,100 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2012-2013 ZeroTier Networks LLC
*
* 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 <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QEvent>
#include <QString>
#include <QShowEvent>
#include <QTimerEvent>
#include <QSettings>
#include <map>
#include <vector>
#include <string>
#include "../node/Constants.hpp"
#include "../node/Node.hpp"
#include "../node/Utils.hpp"
namespace Ui {
class MainWindow;
}
// Globally visible instance of local client for communicating with ZT1
// Can be null if not connected, or will point to current
extern ZeroTier::Node::LocalClient *zeroTierClient;
// Globally visible pointer to main app window
extern QMainWindow *mainWindow;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
// Event used to pass messages from the Node::LocalClient thread to the
// main window to update network lists and stats.
class ZTMessageEvent : public QEvent
{
public:
ZTMessageEvent(const std::vector<std::string> &m) :
QEvent(QEvent::User),
ztMessage(m) {}
std::vector<std::string> ztMessage;
};
explicit MainWindow(QWidget *parent = 0);
virtual ~MainWindow();
protected:
virtual void timerEvent(QTimerEvent *event);
virtual void customEvent(QEvent *event);
private slots:
void on_joinNetworkButton_clicked();
void on_actionAbout_triggered();
void on_networkIdLineEdit_textChanged(const QString &text);
void on_addressButton_clicked();
void on_actionQuick_Start_triggered();
private:
Ui::MainWindow *ui;
QString myAddress;
QString myStatus;
QString myVersion;
bool firstTimerTick;
int pollServiceTimerId;
unsigned int numPeers;
unsigned int cyclesSinceResponseFromService;
std::map< std::string,std::vector<std::string> > networks;
};
#endif // MAINWINDOW_H

306
ZeroTierUI/mainwindow.ui Normal file
View File

@ -0,0 +1,306 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>720</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>ZeroTier One</string>
</property>
<property name="windowIcon">
<iconset resource="resources.qrc">
<normaloff>:/img/zt1icon.png</normaloff>:/img/zt1icon.png</iconset>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="noNetworksLabel">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="text">
<string>You Have Not Joined Any Networks</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>25</number>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="networkListWidget">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="autoScroll">
<bool>false</bool>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="spacing">
<number>0</number>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="bottomContainerWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="addressButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Courier</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="statusTip">
<string>Your 10-digit ZeroTier address; click to copy to clipboard.</string>
</property>
<property name="text">
<string notr="true">----------</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextOnly</enum>
</property>
<property name="class" stdset="0">
<string notr="true">clickToCopy</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="statusLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="statusTip">
<string>Your network connection status.</string>
</property>
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="networkIdLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Courier</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="statusTip">
<string>Enter a hexadecimal network ID to join a network.</string>
</property>
<property name="maxLength">
<number>16</number>
</property>
<property name="frame">
<bool>true</bool>
</property>
<property name="placeholderText">
<string>(Network ID)</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="joinNetworkButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Courier</family>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="statusTip">
<string>Join this network.</string>
</property>
<property name="text">
<string notr="true">+</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>720</width>
<height>22</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>Help</string>
</property>
<addaction name="actionAbout"/>
<addaction name="actionQuick_Start"/>
</widget>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="separator"/>
<addaction name="actionExit"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QStatusBar" name="statusBar">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
</widget>
<action name="actionAbout">
<property name="text">
<string>About</string>
</property>
</action>
<action name="actionExit">
<property name="text">
<string>Exit</string>
</property>
</action>
<action name="actionQuick_Start">
<property name="text">
<string>Quick Start</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="resources.qrc"/>
</resources>
<connections>
<connection>
<sender>actionExit</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>333</x>
<y>149</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,179 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2012-2013 ZeroTier Networks LLC
*
* 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 <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#include "networkwidget.h"
#include "mainwindow.h"
#include "ui_networkwidget.h"
#include "onetimedialog.h"
#include "main.h"
#include <QClipboard>
#include <QString>
#include <QStringList>
#include <QCoreApplication>
#include <QProcess>
#include <QList>
#include <QMessageBox>
#include <QFont>
#include "../node/Constants.hpp"
NetworkWidget::NetworkWidget(QWidget *parent,const std::string &nwid) :
QWidget(parent),
ui(new Ui::NetworkWidget),
networkIdStr(nwid),
publicWarningShown(false)
{
ui->setupUi(this);
ui->networkIdButton->setText(QString(nwid.c_str()));
QFontMetrics fm(ui->ipListWidget->font());
int lineHeight = ui->ipListWidget->spacing() + fm.height();
ui->ipListWidget->setMinimumHeight(lineHeight * 4);
ui->ipListWidget->setMaximumHeight(lineHeight * 4);
#ifdef __APPLE__
QWidgetList widgets = this->findChildren<QWidget*>();
foreach(QWidget* widget, widgets)
widget->setAttribute(Qt::WA_MacShowFocusRect,false);
#endif
#ifdef __WINDOWS__
QWidgetList widgets = this->findChildren<QWidget*>();
foreach(QWidget *widget, widgets) {
QFont font(widget->font());
font.setPointSizeF(font.pointSizeF() * 0.75);
widget->setFont(font);
}
#endif
}
NetworkWidget::~NetworkWidget()
{
delete ui;
}
void NetworkWidget::setStatus(const std::string &status,const std::string &age)
{
ui->statusLabel->setText(QString(status.c_str()));
if (status == "OK")
ui->ageLabel->setText(QString("[") + age.c_str() + "s ago]");
else ui->ageLabel->setText(QString());
}
void NetworkWidget::setNetworkName(const std::string &name)
{
if (name == "?") {
ui->nameLabel->setText("... waiting ...");
ui->nameLabel->setEnabled(false);
} else {
ui->nameLabel->setText(QString(name.c_str()));
ui->nameLabel->setEnabled(true);
}
}
void NetworkWidget::setNetworkType(const std::string &type)
{
ui->networkTypeLabel->setText(QString(type.c_str()));
if (type == "?")
ui->networkTypeLabel->setStatusTip("Waiting for configuration...");
else if (type == "public") {
if ((!publicWarningShown)&&(!settings->value("shown_publicWarning",false).toBool())) {
publicWarningShown = true;
OneTimeDialog *d = new OneTimeDialog(mainWindow,"shown_publicWarning","Security Notice","Security Notice:"ZT_EOL_S""ZT_EOL_S"You have joined a public network. Anyone can join these. We recommend making sure that your system's automatic software updates are enabled and turning off any shared network services that you do not want people to access.");
d->setModal(false);
d->show();
}
ui->networkTypeLabel->setStatusTip("This network can be joined by anyone in the world.");
} else if (type == "private")
ui->networkTypeLabel->setStatusTip("This network is private; only authorized peers can join.");
else ui->networkTypeLabel->setStatusTip("Unknown network type.");
}
void NetworkWidget::setNetworkDeviceName(const std::string &dev)
{
ui->deviceLabel->setText(QString(dev.c_str()));
}
void NetworkWidget::setIps(const std::string &commaSeparatedList)
{
QStringList ips(QString(commaSeparatedList.c_str()).split(QChar(','),QString::SkipEmptyParts));
if (commaSeparatedList == "-")
ips.clear();
QStringList tmp;
ips.sort();
for(QStringList::iterator i(ips.begin());i!=ips.end();++i) {
QString ipOnly(*i);
int slashIdx = ipOnly.indexOf('/');
if (slashIdx > 0)
ipOnly.truncate(slashIdx);
tmp.append(ipOnly);
}
ips = tmp;
for(QStringList::iterator i(ips.begin());i!=ips.end();++i) {
if (ui->ipListWidget->findItems(*i,Qt::MatchCaseSensitive).size() == 0)
ui->ipListWidget->addItem(*i);
}
for(int i=0;i<ui->ipListWidget->count();++i) {
QListWidgetItem *item = ui->ipListWidget->item(i);
if (!ips.contains(item->text()))
ui->ipListWidget->removeItemWidget(item);
}
}
const std::string &NetworkWidget::networkId()
{
return networkIdStr;
}
void NetworkWidget::on_leaveNetworkButton_clicked()
{
if (QMessageBox::question(this,"Leave Network?",QString("Are you sure you want to leave network '") + networkIdStr.c_str() + "'?",QMessageBox::No,QMessageBox::Yes) == QMessageBox::Yes) {
this->setEnabled(false);
zeroTierClient->send((QString("leave ") + networkIdStr.c_str()).toStdString());
}
}
void NetworkWidget::on_networkIdButton_clicked()
{
QApplication::clipboard()->setText(ui->networkIdButton->text());
}
void NetworkWidget::on_ipListWidget_itemActivated(QListWidgetItem *item)
{
if (item)
QApplication::clipboard()->setText(item->text());
}
void NetworkWidget::on_ipListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
if (current)
QApplication::clipboard()->setText(current->text());
}

View File

@ -0,0 +1,68 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2012-2013 ZeroTier Networks LLC
*
* 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 <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#ifndef NETWORK_H
#define NETWORK_H
#include <string>
#include <QWidget>
#include <QListWidgetItem>
namespace Ui {
class NetworkWidget;
}
class NetworkWidget : public QWidget
{
Q_OBJECT
public:
explicit NetworkWidget(QWidget *parent = 0,const std::string &nwid = std::string());
virtual ~NetworkWidget();
void setStatus(const std::string &status,const std::string &age);
void setNetworkName(const std::string &name);
void setNetworkType(const std::string &type);
void setNetworkDeviceName(const std::string &dev);
void setIps(const std::string &commaSeparatedList);
const std::string &networkId();
private slots:
void on_leaveNetworkButton_clicked();
void on_networkIdButton_clicked();
void on_ipListWidget_itemActivated(QListWidgetItem *item);
void on_ipListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
private:
Ui::NetworkWidget *ui;
std::string networkIdStr;
bool publicWarningShown;
};
#endif // NETWORK_H

560
ZeroTierUI/networkwidget.ui Normal file
View File

@ -0,0 +1,560 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NetworkWidget</class>
<widget class="QWidget" name="NetworkWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>580</width>
<height>253</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Network</string>
</property>
<property name="class" stdset="0">
<string notr="true">networkListItem</string>
</property>
<layout class="QHBoxLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="leftWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="networkIdButton">
<property name="font">
<font>
<family>Courier</family>
<pointsize>13</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="statusTip">
<string>Hexadecimal network ID; click to copy to clipboard.</string>
</property>
<property name="text">
<string notr="true">----------------</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextOnly</enum>
</property>
<property name="class" stdset="0">
<string notr="true">clickToCopy</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>[</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="nameLabel">
<property name="font">
<font>
<pointsize>13</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="statusTip">
<string>This network's short name.</string>
</property>
<property name="text">
<string>networkname</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
<property name="class" stdset="0">
<string notr="true">networkName</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>]</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="networkStatsWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<property name="rowWrapPolicy">
<enum>QFormLayout::DontWrapRows</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="formAlignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
<property name="horizontalSpacing">
<number>4</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Type:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="networkTypeLabel">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="statusTip">
<string>What kind of network? Public or private?</string>
</property>
<property name="text">
<string>?</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Status:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Device:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>12</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="statusLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="statusTip">
<string>Status of this network.</string>
</property>
<property name="text">
<string>?</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="ageLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="statusTip">
<string>How recently did this network refresh its settings?</string>
</property>
<property name="text">
<string>[0s ago]</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="deviceLabel">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="statusTip">
<string>The name of the network device on your system.</string>
</property>
<property name="text">
<string>?</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="rightWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
<underline>false</underline>
</font>
</property>
<property name="styleSheet">
<string notr="true">padding: 0.1em 0 0.1em 0;</string>
</property>
<property name="text">
<string>IP Addresses</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="ipListWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<family>Courier</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="statusTip">
<string>IP addresses assigned to this interface; click to copy to clipboard.</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="class" stdset="0">
<string notr="true">ipAddressList</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="leaveButtonContainerWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="leaveNetworkButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="statusTip">
<string>Leave this network.</string>
</property>
<property name="text">
<string>Leave Network</string>
</property>
<property name="class" stdset="0">
<string notr="true">leaveNetworkButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>ipListWidget</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,37 @@
#include "onetimedialog.h"
#include "ui_onetimedialog.h"
#include "main.h"
OneTimeDialog::OneTimeDialog(QWidget *parent,const char *propName,const QString &title,const QString &message) :
QDialog(parent),
ui(new Ui::OneTimeDialog)
{
ui->setupUi(this);
ui->label->setText(message);
this->setWindowTitle(title);
_propName = propName;
#ifdef __WINDOWS__
QWidgetList widgets = this->findChildren<QWidget*>();
foreach(QWidget *widget, widgets) {
QFont font(widget->font());
font.setPointSizeF(font.pointSizeF() * 0.75);
widget->setFont(font);
}
#endif
}
OneTimeDialog::~OneTimeDialog()
{
delete ui;
}
void OneTimeDialog::on_pushButton_clicked()
{
if (_propName) {
settings->setValue(_propName,ui->checkBox->isChecked());
settings->sync();
}
this->close();
}

View File

@ -0,0 +1,26 @@
#ifndef ONETIMEDIALOG_H
#define ONETIMEDIALOG_H
#include <QDialog>
namespace Ui {
class OneTimeDialog;
}
class OneTimeDialog : public QDialog
{
Q_OBJECT
public:
explicit OneTimeDialog(QWidget *parent = 0,const char *propName = (const char *)0,const QString &title = QString(),const QString &message = QString());
~OneTimeDialog();
private slots:
void on_pushButton_clicked();
private:
Ui::OneTimeDialog *ui;
const char *_propName;
};
#endif // ONETIMEDIALOG_H

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OneTimeDialog</class>
<widget class="QDialog" name="OneTimeDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>496</width>
<height>197</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>12</number>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QCheckBox" name="checkBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Don't Show This Message Again</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QuickstartDialog</class>
<widget class="QDialog" name="QuickstartDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>480</height>
</rect>
</property>
<property name="windowTitle">
<string>Quick Start</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>785</width>
<height>800</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="styleSheet">
<string notr="true">background: #000000;</string>
</property>
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="pixmap">
<pixmap resource="resources.qrc">:/img/ZT1GUI.png</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Select Help -&gt; Quick Start to see this screen again.</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>702</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="okButton">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="resources.qrc"/>
</resources>
<connections>
<connection>
<sender>okButton</sender>
<signal>clicked()</signal>
<receiver>QuickstartDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>753</x>
<y>457</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>239</y>
</hint>
</hints>
</connection>
</connections>
</ui>

9
ZeroTierUI/resources.qrc Normal file
View File

@ -0,0 +1,9 @@
<RCC>
<qresource prefix="/img">
<file>zt1icon.png</file>
<file>ZT1GUI.png</file>
</qresource>
<qresource prefix="/css">
<file>stylesheet.css</file>
</qresource>
</RCC>

106
ZeroTierUI/stylesheet.css Normal file
View File

@ -0,0 +1,106 @@
QToolButton {
margin: 0;
padding: 2px;
text-align: center;
background: palette(button);
color: palette(button-text);
border: 1px solid transparent;
}
QToolButton:focus {
border: 1px solid #000000;
}
QToolButton:hover {
background: palette(highlight);
color: palette(highlight-text);
}
QToolButton:pressed {
border: 1px solid #000000;
}
QToolButton.clickToCopy {
padding: 0;
margin: 0;
border: 0;
background: transparent;
color: palette(link);
}
QToolButton.clickToCopy:focus {
text-decoration: underline;
}
QToolButton.clickToCopy:hover {
text-decoration: underline;
}
QToolButton.clickToCopy:pressed {
background: transparent;
}
QToolButton.leaveNetworkButton {
margin: 0 4px 3px 0;
}
QMainWindow {
background: palette(dark);
}
QListWidget {
background: transparent;
padding: 0;
margin: 0;
border: 0;
}
QListWidget::item {
background: palette(base);
margin: 1px 0 1px 0;
}
QListWidget.ipAddressList {
background: palette(button);
margin: 0 4px 4px 0;
}
QListWidget.ipAddressList::item {
background: transparent;
color: palette(link);
border-bottom: 1px solid transparent;
}
QListWidget.ipAddressList::item:selected {
background: transparent;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid transparent;
}
QListWidget.ipAddressList::item:hover {
border-bottom: 1px solid palette(link);
}
QStatusBar {
background: palette(button);
}
QLabel.networkName {
padding: 0;
margin: 0;
}
#networkIdButton {
padding: 0.2em 0 0 0;
}
#joinNetworkButton {
margin: 1px;
padding: 0;
}
#noNetworksLabel {
background: transparent;
color: #ffffff;
}
#networkListWidget {
background: palette(dark);
margin: 0 0 2px 0;
}
#bottomContainerWidget {
background: palette(base);
}

BIN
ZeroTierUI/zt1icon.icns Normal file

Binary file not shown.

BIN
ZeroTierUI/zt1icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

BIN
ZeroTierUI/zt1icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -0,0 +1,3 @@
This is a do-nothing placebo software update for internal testing. It's a
shell script that just prints a simple message and an .NFO file that signs
it as official.

View File

@ -0,0 +1,6 @@
vMajor=999
vMinor=999
vRevision=999
signedBy=e9bc3707b5
ed25519=ca7b943ace5451f420f1f599822d7013534a7cb7997096141e6a1aa6398c5f260c19dc5eecb297c922950f26dee7f9db787f8dbf85bc422baf3bff94c1131e086a7fc85c26dbb8c1b0a9cae63acc34998d9e1ce553156ea5638f9c99a50f6e2e
url=http://download.zerotier.com/update/update-dummy.sh

View File

@ -0,0 +1,4 @@
#!/bin/bash
echo "Dummy updater -- run with opts: $*"
exit 0

102
buildinstaller.sh Executable file
View File

@ -0,0 +1,102 @@
#!/bin/bash
# This script builds the installer for *nix systems. Windows must do everything
# completely differently, as usual.
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
if [ ! -f zerotier-one ]; then
echo "Could not find 'zerotier-one' binary, please build before running this script."
exit 2
fi
machine=`uname -m`
system=`uname -s`
vmajor=`cat version.h | grep -F ZEROTIER_ONE_VERSION_MAJOR | cut -d ' ' -f 3`
vminor=`cat version.h | grep -F ZEROTIER_ONE_VERSION_MINOR | cut -d ' ' -f 3`
revision=`cat version.h | grep -F ZEROTIER_ONE_VERSION_REVISION | cut -d ' ' -f 3`
if [ -z "$vmajor" -o -z "$vminor" -o -z "$revision" ]; then
echo "Unable to extract version info from version.h, aborting installer build."
exit 2
fi
rm -rf build-installer
mkdir build-installer
case "$system" in
Linux)
# Canonicalize $machine for some architectures... we use x86
# and x64 for Intel stuff. ARM and others should be fine if
# we ever ship officially for those.
case "$machine" in
i386|i486|i586|i686)
machine="x86"
;;
x86_64|amd64|x64)
machine="x64"
;;
*)
echo "Unsupported machine type: $machine"
exit 2
esac
echo "Assembling Linux installer for $machine and version $vmajor.$vminor.$revision"
mkdir -p 'build-installer/var/lib/zerotier-one'
cp -fp 'ext/installfiles/linux/uninstall.sh' 'build-installer/var/lib/zerotier-one'
cp -fp 'zerotier-one' 'build-installer/var/lib/zerotier-one'
mkdir -p 'build-installer/tmp'
cp -fp 'ext/installfiles/linux/init.d/zerotier-one' 'build-installer/tmp/init.d_zerotier-one'
cp -fp 'ext/installfiles/linux/systemd/zerotier-one.service' 'build-installer/tmp/systemd_zerotier-one.service'
targ="ZeroTierOneInstaller-linux-${machine}-${vmajor}_${vminor}_${revision}"
# Use gzip in Linux since some minimal Linux systems do not have bunzip2
rm -f build-installer-tmp.tar.gz
cd build-installer
tar -cf - * | gzip -9 >../build-installer-tmp.tar.gz
cd ..
rm -f $targ
cat ext/installfiles/linux/install.tmpl.sh build-installer-tmp.tar.gz >$targ
chmod 0755 $targ
rm -f build-installer-tmp.tar.gz
ls -l $targ
;;
Darwin)
echo "Assembling mac installer for x86/x64 (combined) version $vmajor.$vminor.$revision"
mkdir -p 'build-installer/Applications'
cp -a 'build-ZeroTierUI-release/ZeroTier One.app' 'build-installer/Applications'
mkdir -p 'build-installer/Library/Application Support/ZeroTier/One'
cp -fp 'ext/installfiles/mac/uninstall.sh' 'build-installer/Library/Application Support/ZeroTier/One'
cp -fp 'ext/installfiles/mac/launch.sh' 'build-installer/Library/Application Support/ZeroTier/One'
cp -fp 'zerotier-one' 'build-installer/Library/Application Support/ZeroTier/One'
cp -fRp ext/bin/tap-mac/* 'build-installer/Library/Application Support/ZeroTier/One'
mkdir -p 'build-installer/Library/LaunchDaemons'
cp -fp 'ext/installfiles/mac/com.zerotier.one.plist' 'build-installer/Library/LaunchDaemons'
targ="ZeroTierOneInstaller-mac-combined-${vmajor}_${vminor}_${revision}"
rm -f build-installer-tmp.tar.bz2
cd build-installer
find . -type f -name .DS_Store -print0 | xargs -0 rm -f
tar -cf - * | bzip2 -9 >../build-installer-tmp.tar.bz2
cd ..
rm -f $targ
cat ext/installfiles/mac/install.tmpl.sh build-installer-tmp.tar.bz2 >$targ
chmod 0755 $targ
rm -f build-installer-tmp.tar.bz2
ls -l $targ
;;
*)
echo "Unsupported platform: $system"
exit 2
esac
exit 0

148
cli.cpp
View File

@ -1,148 +0,0 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2012-2013 ZeroTier Networks LLC
*
* 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 <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef __WINDOWS__
#include <unistd.h>
#endif
#include "node/Node.hpp"
#include "node/Constants.hpp"
#include "node/Utils.hpp"
#include "node/Thread.hpp"
#include "node/Condition.hpp"
using namespace ZeroTier;
static void printHelp(FILE *out,const char *exename)
{
fprintf(out,"Usage: %s [-switches] <command>"ZT_EOL_S,exename);
fprintf(out,ZT_EOL_S);
fprintf(out,"Available switches:"ZT_EOL_S);
fprintf(out," -c<port> - Communicate with daemon over this local port"ZT_EOL_S);
fprintf(out," -t<token> - Specify token on command line"ZT_EOL_S);
fprintf(out," -T<file> - Read token from file"ZT_EOL_S);
fprintf(out,ZT_EOL_S);
fprintf(out,"Use the 'help' command to get help from ZeroTier One itself."ZT_EOL_S);
}
static volatile unsigned int numResults = 0;
static Condition doneCondition;
static void resultHandler(void *arg,unsigned long id,const char *line)
{
++numResults;
if (strlen(line))
fprintf(stdout,"%s"ZT_EOL_S,line);
else doneCondition.signal();
}
int main(int argc,char **argv)
{
if (argc <= 1) {
printHelp(stdout,argv[0]);
return -1;
}
std::string authToken;
std::string command;
bool pastSwitches = false;
unsigned int controlPort = 0;
for(int i=1;i<argc;++i) {
if ((argv[i][0] == '-')&&(!pastSwitches)) {
if (strlen(argv[i]) <= 1) {
printHelp(stdout,argv[0]);
return -1;
}
switch(argv[i][1]) {
case 'c':
controlPort = Utils::strToUInt(argv[i] + 2);
break;
case 't':
authToken.assign(argv[i] + 2);
break;
case 'T':
if (!Utils::readFile(argv[i] + 2,authToken)) {
fprintf(stdout,"FATAL ERROR: unable to read token from '%s'"ZT_EOL_S,argv[i] + 2);
return -2;
}
break;
default:
return -1;
}
} else {
pastSwitches = true;
if (command.length())
command.push_back(' ');
command.append(argv[i]);
}
}
if (!authToken.length()) {
const char *home = getenv("HOME");
if (home) {
std::string dotZeroTierAuthToken(home);
dotZeroTierAuthToken.push_back(ZT_PATH_SEPARATOR);
dotZeroTierAuthToken.append(".zerotierOneAuthToken");
if (!Utils::readFile(dotZeroTierAuthToken.c_str(),authToken)) {
#ifndef __WINDOWS__
#ifdef __APPLE__
const char *systemAuthTokenPath = "/Library/Application Support/ZeroTier/One/authtoken.secret";
#else
const char *systemAuthTokenPath = "/var/lib/zerotier-one/authtoken.secret";
#endif
if (!Utils::readFile(systemAuthTokenPath,authToken)) {
fprintf(stdout,"FATAL ERROR: no token specified on command line and could not read '%s' or '%s'"ZT_EOL_S,dotZeroTierAuthToken.c_str(),systemAuthTokenPath);
return -2;
}
#else // __WINDOWS__
fprintf(stdout,"FATAL ERROR: no token specified on command line and could not read '%s'"ZT_EOL_S,dotZeroTierAuthToken.c_str());
return -2;
#endif // __WINDOWS__
}
}
}
if (!authToken.length()) {
fprintf(stdout,"FATAL ERROR: could not find auth token"ZT_EOL_S);
return -2;
}
Node::LocalClient client(authToken.c_str(),controlPort,&resultHandler,(void *)0);
client.send(command.c_str());
doneCondition.wait(1000);
if (!numResults) {
fprintf(stdout,"ERROR: no results received. Is ZeroTier One running?"ZT_EOL_S);
return -1;
}
return 0;
}

View File

@ -3,5 +3,5 @@ fair game to redistribute. It's packaged with OpenVPN and several
other things and also distributed in source code form as an example
program by Microsoft.
It's used to automatically install the Microsoft Loopback Adapter
or remove it when no longer needed.
It's called by zerotier-one.exe to automagically install and remove
instances of the tap device.

View File

@ -3,21 +3,21 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>@@CFBUNDLEDEVELOPMENTREGION@@</string>
<string>English</string>
<key>CFBundleExecutable</key>
<string>@@CFBUNDLEEXECUTABLE@@</string>
<string>tap</string>
<key>CFBundleIdentifier</key>
<string>@@CFBUNDLEIDENTIFIER@@</string>
<string>com.zerotier.tap</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>@@CFBUNDLEEXECUTABLE@@</string>
<string>tap</string>
<key>CFBundlePackageType</key>
<string>@@CFBUNDLEPACKAGETYPE@@</string>
<string>KEXT</string>
<key>CFBundleShortVersionString</key>
<string>@@CFBUNDLEVERSION@@</string>
<string>20131028</string>
<key>CFBundleSignature</key>
<string>@@CFBUNDLESIGNATURE@@</string>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>OSBundleLibraries</key>

Binary file not shown.

View File

@ -0,0 +1,105 @@
<?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>files</key>
<dict/>
<key>files2</key>
<dict/>
<key>rules</key>
<dict>
<key>^Resources/</key>
<true/>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^.*</key>
<true/>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^[^/]+$</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -3,39 +3,40 @@ Signature="$WINDOWS NT$"
Class=Net
ClassGuid={4d36e972-e325-11ce-bfc1-08002be10318}
Provider=%Provider%
CatalogFile=ztTap100.cat
CatalogFile=zttap200.cat
DriverVer=01/23/2014,15.19.17.816
[Strings]
DeviceDescription = "ZeroTier One Ethernet Tap"
Provider = "ZeroTier Networks"
DeviceDescription = "ZeroTier One Virtual Network Port"
Provider = "ZeroTier Networks LLC"
; To build for x86, take NTamd64 off this and off the named section manually, build, then put it back!
[Manufacturer]
%Provider%=ztTap100,NTamd64
%Provider%=zttap200,NTamd64
[ztTap100]
%DeviceDescription%=ztTap100.ndi,ztTap100
[zttap200]
%DeviceDescription%=zttap200.ndi,zttap200
[ztTap100.NTamd64]
%DeviceDescription%=ztTap100.ndi,ztTap100
[ztTap200.NTamd64]
%DeviceDescription%=zttap200.ndi,zttap200
[ztTap100.ndi]
CopyFiles = ztTap100.driver,ztTap100.files
AddReg = ztTap100.reg
AddReg = ztTap100.params.reg
[zttap200.ndi]
CopyFiles = zttap200.driver,zttap200.files
AddReg = zttap200.reg
AddReg = zttap200.params.reg
Characteristics = 0x81
[ztTap100.ndi.Services]
AddService = ztTap100, 2, ztTap100.service
[zttap200.ndi.Services]
AddService = zttap200, 2, zttap200.service
[ztTap100.reg]
HKR, Ndi, Service, 0, "ztTap100"
[zttap200.reg]
HKR, Ndi, Service, 0, "zttap200"
HKR, Ndi\Interfaces, UpperRange, 0, "ndis5"
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
HKR, , Manufacturer, 0, "%Provider%"
HKR, , ProductName, 0, "%DeviceDescription%"
[ztTap100.params.reg]
[zttap200.params.reg]
HKR, Ndi\params\MTU, ParamDesc, 0, "MTU"
HKR, Ndi\params\MTU, Type, 0, "int"
HKR, Ndi\params\MTU, Default, 0, "2800"
@ -52,33 +53,27 @@ HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected"
HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address"
HKR, Ndi\params\MAC, Type, 0, "edit"
HKR, Ndi\params\MAC, Optional, 0, "1"
HKR, Ndi\params\AllowNonAdmin, ParamDesc, 0, "Non-Admin Access"
HKR, Ndi\params\AllowNonAdmin, Type, 0, "enum"
HKR, Ndi\params\AllowNonAdmin, Default, 0, "0"
HKR, Ndi\params\AllowNonAdmin, Optional, 0, "0"
HKR, Ndi\params\AllowNonAdmin\enum, "0", 0, "Not Allowed"
HKR, Ndi\params\AllowNonAdmin\enum, "1", 0, "Allowed"
[ztTap100.service]
[zttap200.service]
DisplayName = %DeviceDescription%
ServiceType = 1
StartType = 3
ErrorControl = 1
LoadOrderGroup = NDIS
ServiceBinary = %12%\ztTap100.sys
ServiceBinary = %12%\zttap200.sys
[SourceDisksNames]
1 = %DeviceDescription%, ztTap100.sys
1 = %DeviceDescription%, zttap200.sys
[SourceDisksFiles]
ztTap100.sys = 1
zttap200.sys = 1
[DestinationDirs]
ztTap100.files = 11
ztTap100.driver = 12
zttap200.files = 11
zttap200.driver = 12
[ztTap100.files]
[zttap200.files]
;
[ztTap100.driver]
ztTap100.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK
[zttap200.driver]
zttap200.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -3,40 +3,37 @@ Signature="$WINDOWS NT$"
Class=Net
ClassGuid={4d36e972-e325-11ce-bfc1-08002be10318}
Provider=%Provider%
CatalogFile=ztTap100.cat
DriverVer=08/24/2013,16.12.30.608
CatalogFile=zttap200.cat
DriverVer=01/24/2014,17.25.51.226
[Strings]
DeviceDescription = "ZeroTier One Ethernet Tap"
Provider = "ZeroTier Networks"
DeviceDescription = "ZeroTier One Virtual Network Port"
Provider = "ZeroTier Networks LLC"
; To build for x86, take NTamd64 off this and off the named section manually, build, then put it back!
[Manufacturer]
%Provider%=ztTap100,NTamd64
%Provider%=zttap200
[ztTap100]
%DeviceDescription%=ztTap100.ndi,ztTap100
[zttap200]
%DeviceDescription%=zttap200.ndi,zttap200
[ztTap100.NTamd64]
%DeviceDescription%=ztTap100.ndi,ztTap100
[ztTap100.ndi]
CopyFiles = ztTap100.driver,ztTap100.files
AddReg = ztTap100.reg
AddReg = ztTap100.params.reg
[zttap200.ndi]
CopyFiles = zttap200.driver,zttap200.files
AddReg = zttap200.reg
AddReg = zttap200.params.reg
Characteristics = 0x81
[ztTap100.ndi.Services]
AddService = ztTap100, 2, ztTap100.service
[zttap200.ndi.Services]
AddService = zttap200, 2, zttap200.service
[ztTap100.reg]
HKR, Ndi, Service, 0, "ztTap100"
[zttap200.reg]
HKR, Ndi, Service, 0, "zttap200"
HKR, Ndi\Interfaces, UpperRange, 0, "ndis5"
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
HKR, , Manufacturer, 0, "%Provider%"
HKR, , ProductName, 0, "%DeviceDescription%"
[ztTap100.params.reg]
[zttap200.params.reg]
HKR, Ndi\params\MTU, ParamDesc, 0, "MTU"
HKR, Ndi\params\MTU, Type, 0, "int"
HKR, Ndi\params\MTU, Default, 0, "2800"
@ -53,33 +50,27 @@ HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected"
HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address"
HKR, Ndi\params\MAC, Type, 0, "edit"
HKR, Ndi\params\MAC, Optional, 0, "1"
HKR, Ndi\params\AllowNonAdmin, ParamDesc, 0, "Non-Admin Access"
HKR, Ndi\params\AllowNonAdmin, Type, 0, "enum"
HKR, Ndi\params\AllowNonAdmin, Default, 0, "0"
HKR, Ndi\params\AllowNonAdmin, Optional, 0, "0"
HKR, Ndi\params\AllowNonAdmin\enum, "0", 0, "Not Allowed"
HKR, Ndi\params\AllowNonAdmin\enum, "1", 0, "Allowed"
[ztTap100.service]
[zttap200.service]
DisplayName = %DeviceDescription%
ServiceType = 1
StartType = 3
ErrorControl = 1
LoadOrderGroup = NDIS
ServiceBinary = %12%\ztTap100.sys
ServiceBinary = %12%\zttap200.sys
[SourceDisksNames]
1 = %DeviceDescription%, ztTap100.sys
1 = %DeviceDescription%, zttap200.sys
[SourceDisksFiles]
ztTap100.sys = 1
zttap200.sys = 1
[DestinationDirs]
ztTap100.files = 11
ztTap100.driver = 12
zttap200.files = 11
zttap200.driver = 12
[ztTap100.files]
[zttap200.files]
;
[ztTap100.driver]
ztTap100.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK
[zttap200.driver]
zttap200.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK

Binary file not shown.

View File

@ -0,0 +1,95 @@
#!/bin/sh
#
# zerotier-one Virtual distributed Ethernet service
#
# chkconfig: 2345 11 89
# description: ZeroTier One provides public and private distributed ethernet \
# networks. See https://www.zerotier.com/ for more information.
### BEGIN INIT INFO
# Provides: zerotier-one
# Required-Start: $local_fs $network
# Required-Stop: $local_fs
# Default-Start: 2345
# Default-Stop: 90
# Short-Description: start ZeroTier One
# Description: ZeroTier One provides public and private distributed ethernet \
# networks. See https://www.zerotier.com/ for more information.
### END INIT INFO
#
# This script is written to avoid distro-specific dependencies, so it does not
# use the rc bash script libraries found on some systems. It should work on
# just about anything, even systems using Upstart. Upstart native support may
# come in the future.
#
zthome=/var/lib/zerotier-one
# Add $zthome to path so we can invoke zerotier-one naked, makes it look
# better in a ps listing.
export PATH=/bin:/usr/bin:/sbin:/usr/sbin:$zthome
if [ "$UID" -ne 0 ]; then
echo "Init script must be called as root."
exit 4
fi
if [ ! -f "$zthome/zerotier-one" ]; then
echo "ZeroTier One is not installed in $zthome."
exit 5
fi
pid=0
if [ -f "$zthome/zerotier-one.pid" ]; then
pid=`cat $zthome/zerotier-one.pid`
fi
running=0
if [ "$pid" -gt 0 ]; then
if [ -n "`ls -l /proc/$pid/exe | grep -F zerotier-one`" ]; then
running=1
fi
fi
case "$1" in
start)
if [ $running -gt 0 ]; then
echo "ZeroTier One already running."
exit 0
fi
echo "Starting ZeroTier One..."
nohup zerotier-one >>/dev/null 2>&1 &
disown %1
exit 0
;;
stop)
if [ $running -gt 0 ]; then
echo "Stopping ZeroTier One..."
kill -TERM $pid
else
echo "ZeroTier One is not running."
fi
;;
restart|reload|force-reload|condrestart|try-restart)
echo "Restarting ZeroTier One..."
if [ $running -gt 0 ]; then
kill -TERM $pid
fi
while [ -f "$zthome/zerotier-one.pid" ]; do sleep 1; done
nohup zerotier-one >>/dev/null 2>&1 &
disown %1
;;
status)
if [ $running -gt 0 ]; then
exit 0
else
exit 3
fi
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
exit 0

View File

@ -0,0 +1,117 @@
#!/bin/bash
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
shopt -s expand_aliases
dryRun=0
echo "*** ZeroTier One install/update ***"
if [ "$UID" -ne 0 ]; then
echo "Not running as root so doing dry run (no modifications to system)..."
dryRun=1
fi
# Detect systemd vs. regular init
SYSTEMDUNITDIR=
if [ -e /bin/systemctl -o -e /usr/bin/systemctl -o -e /usr/local/bin/systemctl -o -e /sbin/systemctl -o -e /usr/sbin/systemctl ]; then
if [ -e /usr/bin/pkg-config ]; then
SYSTEMDUNITDIR=`/usr/bin/pkg-config systemd --variable=systemdsystemunitdir`
fi
if [ -z "$SYSTEMDUNITDIR" -o ! -d "$SYSTEMDUNITDIR" ]; then
if [ -d /usr/lib/systemd/system ]; then
SYSTEMDUNITDIR=/usr/lib/systemd/system
fi
if [ -d /etc/systemd/system ]; then
SYSTEMDUNITDIR=/etc/systemd/system
fi
fi
fi
if [ $dryRun -gt 0 ]; then
alias ln="echo '>> dry run: ln'"
alias rm="echo '>> dry run: rm'"
alias mv="echo '>> dry run: mv'"
alias chown="echo '>> dry run: chown'"
alias chgrp="echo '>> dry run: chgrp'"
alias chkconfig="echo '>> dry run: chkconfig'"
alias zerotier-cli="echo '>> dry run: zerotier-cli'"
alias service="echo '>> dry run: service'"
alias systemctl="echo '>> dry run: systemctl'"
fi
scriptPath="`dirname "$0"`/`basename "$0"`"
if [ ! -r "$scriptPath" ]; then
scriptPath="$0"
if [ ! -r "$scriptPath" ]; then
echo "Installer cannot determine its own path; $scriptPath is not readable."
exit 2
fi
fi
endMarkerIndex=`grep -a -b -E '^################' "$scriptPath" | head -c 16 | cut -d : -f 1`
if [ "$endMarkerIndex" -le 100 ]; then
echo 'Internal error: unable to find end of script / start of binary data marker.'
exit 2
fi
blobStart=`expr $endMarkerIndex + 17`
if [ "$blobStart" -le "$endMarkerIndex" ]; then
echo 'Internal error: unable to find end of script / start of binary data marker.'
exit 2
fi
echo 'Extracting files...'
if [ $dryRun -gt 0 ]; then
echo ">> dry run: tail -c +$blobStart \"$scriptPath\" | gunzip -c | tar -xvop -C / -f -"
else
tail -c +$blobStart "$scriptPath" | gunzip -c | tar -xvop --no-overwrite-dir -C / -f -
fi
if [ $dryRun -eq 0 -a ! -d "/var/lib/zerotier-one" ]; then
echo 'Archive extraction failed, cannot find zerotier-one binary in "/var/lib/zerotier-one".'
exit 2
fi
echo 'Installing zerotier-cli command line utility...'
rm -f /usr/bin/zerotier-cli
ln -sf /var/lib/zerotier-one/zerotier-one /usr/bin/zerotier-cli
echo 'Installing and (re-)starting zerotier-one daemon...'
# Note: ensure that service restarts are the last thing this script actually
# does, since these may kill the script itself. Also note the & to allow
# them to finish independently.
if [ -n "$SYSTEMDUNITDIR" -a -d "$SYSTEMDUNITDIR" ]; then
# If this was updated or upgraded from an init.d based system, clean up the old
# init.d stuff before installing directly via systemd.
if [ -f /etc/init.d/zerotier-one ]; then
if [ -e /sbin/chkconfig -o -e /usr/sbin/chkconfig -o -e /bin/chkconfig -o -e /usr/bin/chkconfig ]; then
chkconfig zerotier-one off
fi
rm -f /etc/init.d/zerotier-one
fi
cp -f /tmp/systemd_zerotier-one.service "$SYSTEMDUNITDIR/zerotier-one.service"
rm -f /tmp/systemd_zerotier-one.service /tmp/init.d_zerotier-one
systemctl enable zerotier-one
systemctl restart zerotier-one &
else
cp -f /tmp/init.d_zerotier-one /etc/init.d/zerotier-one
chmod 0755 /etc/init.d/zerotier-one
rm -f /tmp/systemd_zerotier-one.service /tmp/init.d_zerotier-one
chkconfig zerotier-one on
service zerotier-one restart &
fi
sleep 1
exit 0
# Do not remove the last line or add a carriage return to it! The installer
# looks for an unterminated line beginning with 16 #'s in itself to find
# the binary blob data, which is appended after it.
################

View File

@ -0,0 +1,11 @@
[Unit]
Description=ZeroTier One
After=network.target
[Service]
ExecStart=/var/lib/zerotier-one/zerotier-one
Restart=always
KillMode=process
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,72 @@
#!/bin/bash
export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin
if [ "$UID" -ne 0 ]; then
echo "Must be run as root; try: sudo $0"
exit 1
fi
# Detect systemd vs. regular init
SYSTEMDUNITDIR=
if [ -e /bin/systemctl -o -e /usr/bin/systemctl -o -e /usr/local/bin/systemctl -o -e /sbin/systemctl -o -e /usr/sbin/systemctl ]; then
if [ -e /usr/bin/pkg-config ]; then
SYSTEMDUNITDIR=`/usr/bin/pkg-config systemd --variable=systemdsystemunitdir`
fi
if [ -z "$SYSTEMDUNITDIR" -o ! -d "$SYSTEMDUNITDIR" ]; then
if [ -d /usr/lib/systemd/system ]; then
SYSTEMDUNITDIR=/usr/lib/systemd/system
fi
if [ -d /etc/systemd/system ]; then
SYSTEMDUNITDIR=/etc/systemd/system
fi
fi
fi
echo
echo "This will uninstall ZeroTier One, hit CTRL+C to abort."
echo "Waiting 5 seconds..."
sleep 5
echo "Killing any running zerotier-one service..."
if [ -n "$SYSTEMDUNITDIR" -a -d "$SYSTEMDUNITDIR" ]; then
systemctl stop zerotier-one
systemctl disable zerotier-one
else
service stop zerotier-one
fi
sleep 1
killall -q -TERM zerotier-one
sleep 1
killall -q -KILL zerotier-one
if [ -f /etc/init.d/zerotier-one ]; then
echo "Removing SysV init items..."
rm -f /etc/init.d/zerotier-one
find /etc/rc*.d -name '???zerotier-one' -print0 | xargs -0 rm -f
fi
if [ -n "$SYSTEMDUNITDIR" -a -d "$SYSTEMDUNITDIR" -a -f "$SYSTEMDUNITDIR/zerotier-one.service" ]; then
echo "Removing systemd service..."
rm -f "$SYSTEMDUNITDIR/zerotier-one.service"
fi
echo "Erasing binary and support files..."
if [ -d /var/lib/zerotier-one ]; then
cd /var/lib/zerotier-one
rm -rf zerotier-one *.persist identity.public *.log *.pid *.sh updates.d networks.d iddb.d
fi
echo "Erasing anything installed into system bin directories..."
rm -f /usr/local/bin/zerotier-cli /usr/bin/zerotier-cli
echo "Done."
echo
echo "Your ZeroTier One identity is still preserved in /var/lib/zerotier-one"
echo "as identity.secret and can be manually deleted if you wish. Save it if"
echo "you wish to re-use the address of this node, as it cannot be regenerated."
echo
exit 0

View File

@ -0,0 +1,22 @@
<?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>com.zerotier.one</string>
<key>UserName</key>
<string>root</string>
<key>ProgramArguments</key>
<array>
<string>/Library/Application Support/ZeroTier/One/launch.sh</string>
</array>
<key>WorkingDirectory</key>
<string>/Library/Application Support/ZeroTier/One</string>
<key>StandardOutPath</key>
<string>/dev/null</string>
<key>StandardErrorPath</key>
<string>/dev/null</string>
<key>KeepAlive</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,143 @@
#!/bin/bash
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
shopt -s expand_aliases
dryRun=0
echo "*** ZeroTier One install/update ***"
if [ "$UID" -ne 0 ]; then
echo "Not running as root so doing dry run (no modifications to system)..."
dryRun=1
fi
if [ $dryRun -gt 0 ]; then
alias ln="echo '>> dry run: ln'"
alias rm="echo '>> dry run: rm'"
alias mv="echo '>> dry run: mv'"
alias cp="echo '>> dry run: cp'"
alias chown="echo '>> dry run: chown'"
alias chgrp="echo '>> dry run: chgrp'"
alias chmod="echo '>> dry run: chmod'"
alias launchctl="echo '>> dry run: launchctl'"
alias zerotier-cli="echo '>> dry run: zerotier-cli'"
fi
zthome="/Library/Application Support/ZeroTier/One"
ztapp="/Applications/ZeroTier One.app"
if [ ! -d "$ztapp" ]; then
ztapp=`mdfind kMDItemCFBundleIdentifier == 'com.zerotier.ZeroTierOne' | grep -E '.*ZeroTier One[.]app$' | grep -v -F '/build-' | grep -v -F '/Volumes/ZeroTier' | sort | head -n 1`
fi
scriptPath="`dirname "$0"`/`basename "$0"`"
if [ ! -r "$scriptPath" ]; then
scriptPath="$0"
if [ ! -r "$scriptPath" ]; then
echo "Installer cannot determine its own path; $scriptPath is not readable."
exit 2
fi
fi
endMarkerIndex=`grep -a -b -E '^################' "$scriptPath" | head -c 16 | cut -d : -f 1`
if [ "$endMarkerIndex" -le 100 ]; then
echo 'Internal error: unable to find end of script / start of binary data marker.'
exit 2
fi
blobStart=`expr $endMarkerIndex + 17`
if [ "$blobStart" -le "$endMarkerIndex" ]; then
echo 'Internal error: unable to find end of script / start of binary data marker.'
exit 2
fi
echo 'Extracting files...'
if [ $dryRun -gt 0 ]; then
echo ">> dry run: tail -c +$blobStart \"$scriptPath\" | bunzip2 -c | tar -xvop -C / -f -"
else
rm -rf '/tmp/_zt1tmp'
mkdir '/tmp/_zt1tmp'
tail -c +$blobStart "$scriptPath" | bunzip2 -c | tar -xop -C '/tmp/_zt1tmp' -f -
fi
cd '/tmp/_zt1tmp'
if [ $dryRun -eq 0 -a ! -d './Applications/ZeroTier One.app' ]; then
echo 'Archive extraction failed, cannot find files in /tmp/_zt1tmp.'
exit 2
fi
echo 'Installing zerotier-one service...'
mkdir -p "$zthome"
chown root:admin "$zthome"
chmod 0750 "$zthome"
cp -fa ./Library/Application\ Support/ZeroTier/One/* "$zthome"
chown -R root:wheel "$zthome/tap.kext"
chown -R root:wheel "$zthome/pre10.8/tap.kext"
echo 'Installing/updating ZeroTier One.app...'
if [ ! -z "$ztapp" -a -d "$ztapp" -a -f "$ztapp/Contents/Info.plist" ]; then
# Preserve ownership of current app across updates... that way the admin
# user who dragged it into /Applications can just trash it the way they
# would any other app. This works (due to mdfind up top) even if they put
# it somewhere non-standard on their system.
currentAppOwner=`stat -f '%u' "$ztapp"`
currentAppGroup=`stat -f '%g' "$ztapp"`
rm -rf "$ztapp"
mv -f './Applications/ZeroTier One.app' "$ztapp"
if [ ! -z "$currentAppOwner" -a ! -z "$currentAppGroup" ]; then
chown -R $currentAppOwner "$ztapp"
chgrp -R $currentAppGroup "$ztapp"
else
chown -R root "$ztapp"
chgrp -R admin "$ztapp"
fi
else
# If there is no existing app, just drop the shipped one into place
ztapp="/Applications/ZeroTier One.app"
mv -f './Applications/ZeroTier One.app' "$ztapp"
chown -R root "$ztapp"
chgrp -R admin "$ztapp"
fi
# Set up symlink that watches for app deletion
rm -f "$zthome/shutdownIfUnreadable"
ln -sf "$ztapp/Contents/Info.plist" "$zthome/shutdownIfUnreadable"
echo 'Installing zerotier-cli command line utility...'
rm -f /usr/bin/zerotier-cli
ln -sf "/Library/Application Support/ZeroTier/One/zerotier-one" /usr/bin/zerotier-cli
# This lets the install helper AppleScript thingy go ahead and authorize the
# user after the installer is done, skiping that step for the user who did
# the service install.
if [ ! -f '/Library/Application Support/ZeroTier/One/authtoken.secret' ]; then
echo 'Pre-creating authtoken.secret for ZeroTier service...'
if [ $dryRun -eq 0 ]; then
rm -f '/Library/Application Support/ZeroTier/One/authtoken.secret'
head -c 1024 /dev/urandom | md5 | head -c 24 >'/Library/Application Support/ZeroTier/One/authtoken.secret'
chmod 0600 '/Library/Application Support/ZeroTier/One/authtoken.secret'
fi
fi
echo 'Installing and (re-)starting zerotier-one service via launchctl...'
mv -f './Library/LaunchDaemons/com.zerotier.one.plist' '/Library/LaunchDaemons/'
launchctl load /Library/LaunchDaemons/com.zerotier.one.plist
# launchctl will restart us after exit if this is an online auto-update
cd /tmp
rm -rf _zt1tmp
exit 0
# Do not remove the last line or add a carriage return to it! The installer
# looks for an unterminated line beginning with 16 #'s in itself to find
# the binary blob data, which is appended after it.
################

15
ext/installfiles/mac/launch.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
zthome="/Library/Application Support/ZeroTier/One"
export PATH="/bin:/usr/bin:/sbin:/usr/sbin:$zthome"
# If the app has been deleted, uninstall the service
cd "$zthome"
if [ -L './shutdownIfUnreadable' -a ! -f "`readlink ./shutdownIfUnreadable`" ]; then
rm -f /tmp/ZeroTierOneUninstall.log
/bin/bash "$zthome/uninstall.sh" >/tmp/ZeroTierOneUninstall.log 2>&1
exit 0
fi
# Launch ZeroTier One (not as daemon... launchd monitors it)
exec zerotier-one

View File

@ -0,0 +1,49 @@
#!/bin/bash
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
zthome="/Library/Application Support/ZeroTier/One"
ztapp="/Applications/ZeroTier One.app"
if [ -z "$ztapp" -o ! -d "$ztapp" ]; then
ztapp=`mdfind kMDItemCFBundleIdentifier == 'com.zerotier.ZeroTierOne' | grep -E '.*ZeroTier One[.]app$' | grep -v -F '/build-' | grep -v -F '/Volumes/ZeroTier' | sort | head -n 1`
fi
if [ "$UID" -ne 0 ]; then
echo "Must be run as root; try: sudo $0"
exit 1
fi
echo "Killing any running zerotier-one service..."
killall -TERM zerotier-one >>/dev/null 2>&1
sleep 3
killall -KILL zerotier-one >>/dev/null 2>&1
sleep 1
echo "Unloading kernel extension..."
kextunload "$zthome/pre10.8/tap.kext" >>/dev/null 2>&1
kextunload "$zthome/tap.kext" >>/dev/null 2>&1
echo "Erasing GUI app (if installed)..."
if [ ! -z "$ztapp" -a -d "$ztapp" -a -f "$ztapp/Contents/Info.plist" ]; then
rm -rf "$ztapp"
fi
echo "Erasing service and support files..."
rm -f /usr/bin/zerotier-cli
cd "$zthome"
rm -f zerotier-one *.persist identity.public *.log *.pid *.sh shutdownIfUnreadable
rm -rf pre10.8 tap.kext updates.d networks.d
echo "Removing LaunchDaemons item..."
rm -f /Library/LaunchDaemons/com.zerotier.one.plist
launchctl remove com.zerotier.one
echo "Done."
echo
echo "Your ZeroTier One identity is still in: $zthome"
echo "as identity.secret and can be manually deleted if you wish. Save it if"
echo "you wish to re-use the address of this node, as it cannot be regenerated."
echo
exit 0

View File

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DOCUMENT Type="Advanced Installer" CreateVersion="10.9" version="10.9" Modules="simple" RootPath="." Language="en" Id="{DC564647-6BF0-4550-87F4-89C938D0159C}">
<COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
<ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
<ROW Property="ALLUSERS" Value="1"/>
<ROW Property="ARPCOMMENTS" Value="This installer database contains the logic and data required to install [|ProductName]." ValueLocId="*"/>
<ROW Property="ARPCONTACT" Value="contact@zerotier.com"/>
<ROW Property="ARPNOMODIFY" MultiBuildValue="DefaultBuild:1"/>
<ROW Property="ARPNOREPAIR" Value="1"/>
<ROW Property="ARPPRODUCTICON" Value="zt1icon.exe" Type="8"/>
<ROW Property="ARPURLINFOABOUT" Value="https://www.zerotier.com/"/>
<ROW Property="LIMITUI" MultiBuildValue="DefaultBuild:1"/>
<ROW Property="MSIFASTINSTALL" MultiBuildValue="DefaultBuild:2"/>
<ROW Property="Manufacturer" Value="ZeroTier Networks LLC"/>
<ROW Property="ProductCode" Value="1033:{24DFCEE7-3AC9-4D39-BD53-974220C12043} " Type="16"/>
<ROW Property="ProductLanguage" Value="1033"/>
<ROW Property="ProductName" Value="ZeroTier One"/>
<ROW Property="ProductVersion" Value="0.7.0" Type="32"/>
<ROW Property="REBOOT" MultiBuildValue="DefaultBuild:ReallySuppress"/>
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND"/>
<ROW Property="UpgradeCode" Value="{B0E2A5F3-88B6-4E77-B922-CB4739B4C4C8}"/>
<ROW Property="WindowsType9X" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/>
<ROW Property="WindowsType9XDisplay" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/>
<ROW Property="WindowsTypeNT" MultiBuildValue="DefaultBuild:Windows 2000, Windows 2000 Service Pack 1, Windows 2000 Service Pack 2, Windows 2000 Service Pack 3, Windows 2000 Service Pack 4, Windows XP x86, Windows XP x86 Service Pack 1, Windows XP x86 Service Pack 2, Windows XP x86 Service Pack 3" ValueLocId="-"/>
<ROW Property="WindowsTypeNT40" MultiBuildValue="DefaultBuild:Windows NT 4.0" ValueLocId="-"/>
<ROW Property="WindowsTypeNT40Display" MultiBuildValue="DefaultBuild:Windows NT 4.0" ValueLocId="-"/>
<ROW Property="WindowsTypeNT64" MultiBuildValue="DefaultBuild:Windows XP x64, Windows XP x64 Service Pack 1, Windows XP x64 Service Pack 2" ValueLocId="-"/>
<ROW Property="WindowsTypeNT64Display" MultiBuildValue="DefaultBuild:Windows XP x64" ValueLocId="-"/>
<ROW Property="WindowsTypeNTDisplay" MultiBuildValue="DefaultBuild:Windows 2000, Windows XP x86" ValueLocId="-"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiDirsComponent">
<ROW Directory="APPDIR" Directory_Parent="TARGETDIR" DefaultDir="APPDIR:." IsPseudoRoot="1"/>
<ROW Directory="TARGETDIR" DefaultDir="SourceDir"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
<ROW Component="ProductInformation" ComponentId="{DB078D04-EA8E-4A7C-9001-89BAD932F9D9}" Directory_="APPDIR" Attributes="4" KeyPath="Version"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="ProductInformation"/>
<ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.BuildComponent">
<ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" Languages="en" InstallationType="4" UseLargeSchema="true"/>
<ATTRIBUTE name="CurrentBuild" value="DefaultBuild"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.CacheComponent">
<ATTRIBUTE name="Enable" value="false"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.DictionaryComponent">
<ROW Path="&lt;AI_DICTS&gt;ui.ail"/>
<ROW Path="&lt;AI_DICTS&gt;ui_en.ail"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.FragmentComponent">
<ROW Fragment="CommonUI.aip" Path="&lt;AI_FRAGS&gt;CommonUI.aip"/>
<ROW Fragment="MaintenanceTypeDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\MaintenanceTypeDlg.aip"/>
<ROW Fragment="MaintenanceWelcomeDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\MaintenanceWelcomeDlg.aip"/>
<ROW Fragment="SequenceDialogs.aip" Path="&lt;AI_THEMES&gt;classic\fragments\SequenceDialogs.aip"/>
<ROW Fragment="Sequences.aip" Path="&lt;AI_FRAGS&gt;Sequences.aip"/>
<ROW Fragment="StaticUIStrings.aip" Path="&lt;AI_FRAGS&gt;StaticUIStrings.aip"/>
<ROW Fragment="UI.aip" Path="&lt;AI_THEMES&gt;classic\fragments\UI.aip"/>
<ROW Fragment="Validation.aip" Path="&lt;AI_FRAGS&gt;Validation.aip"/>
<ROW Fragment="VerifyRemoveDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\VerifyRemoveDlg.aip"/>
<ROW Fragment="VerifyRepairDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\VerifyRepairDlg.aip"/>
<ROW Fragment="WelcomeDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\WelcomeDlg.aip"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent">
<ROW Name="aicustact.dll" SourcePath="&lt;AI_CUSTACTS&gt;aicustact.dll"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlComponent">
<ROW Dialog_="WelcomeDlg" Control="WelcomeDlgDialogInitializer" Type="DialogInitializer" X="0" Y="0" Width="0" Height="0" Attributes="0" Order="-1" TextLocId="-" HelpLocId="-" ExtDataLocId="-"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlEventComponent">
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="EndDialog" Argument="Return" Condition="AI_INSTALL" Ordering="1"/>
<ROW Dialog_="MaintenanceWelcomeDlg" Control_="Next" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="99"/>
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_MAINT" Ordering="198"/>
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="202"/>
<ROW Dialog_="CustomizeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_MAINT" Ordering="101"/>
<ROW Dialog_="CustomizeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="1"/>
<ROW Dialog_="MaintenanceTypeDlg" Control_="ChangeButton" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="501"/>
<ROW Dialog_="MaintenanceTypeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceWelcomeDlg" Condition="AI_MAINT" Ordering="1"/>
<ROW Dialog_="MaintenanceTypeDlg" Control_="RemoveButton" Event="NewDialog" Argument="VerifyRemoveDlg" Condition="AI_MAINT AND InstallMode=&quot;Remove&quot;" Ordering="601"/>
<ROW Dialog_="VerifyRemoveDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode=&quot;Remove&quot;" Ordering="1"/>
<ROW Dialog_="MaintenanceTypeDlg" Control_="RepairButton" Event="NewDialog" Argument="VerifyRepairDlg" Condition="AI_MAINT AND InstallMode=&quot;Repair&quot;" Ordering="601"/>
<ROW Dialog_="VerifyRepairDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode=&quot;Repair&quot;" Ordering="1"/>
<ROW Dialog_="VerifyRepairDlg" Control_="Repair" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode=&quot;Repair&quot;" Ordering="399" Options="1"/>
<ROW Dialog_="VerifyRemoveDlg" Control_="Remove" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode=&quot;Remove&quot;" Ordering="299" Options="1"/>
<ROW Dialog_="PatchWelcomeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_PATCH" Ordering="201"/>
<ROW Dialog_="ResumeDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_RESUME" Ordering="299"/>
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="SpawnDialog" Argument="OutOfRbDiskDlg" Condition="AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST=&quot;P&quot; OR NOT PROMPTROLLBACKCOST)" Ordering="2" Options="2"/>
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="EnableRollback" Argument="False" Condition="AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST=&quot;D&quot;" Ordering="3" Options="2"/>
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="SpawnDialog" Argument="OutOfDiskDlg" Condition="AI_INSTALL AND ( (OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST=&quot;F&quot;) )" Ordering="4" Options="2"/>
<ROW Dialog_="WelcomeDlg" Control_="WelcomeDlgDialogInitializer" Event="[AI_ButtonText_Next_Orig]" Argument="[ButtonText_Next]" Condition="AI_INSTALL" Ordering="0" Options="2"/>
<ROW Dialog_="WelcomeDlg" Control_="WelcomeDlgDialogInitializer" Event="[ButtonText_Next]" Argument="[[AI_CommitButton]]" Condition="AI_INSTALL" Ordering="1" Options="2"/>
<ROW Dialog_="WelcomeDlg" Control_="WelcomeDlgDialogInitializer" Event="[AI_Text_Next_Orig]" Argument="[Text_Next]" Condition="AI_INSTALL" Ordering="2" Options="2"/>
<ROW Dialog_="WelcomeDlg" Control_="WelcomeDlgDialogInitializer" Event="[Text_Next]" Argument="[Text_Install]" Condition="AI_INSTALL" Ordering="3" Options="2"/>
<ROW Dialog_="WelcomeDlg" Control_="Back" Event="[ButtonText_Next]" Argument="[AI_ButtonText_Next_Orig]" Condition="AI_INSTALL" Ordering="0" Options="2"/>
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_PATCH" Ordering="199"/>
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="PatchWelcomeDlg" Condition="AI_PATCH" Ordering="203"/>
<ROW Dialog_="WelcomeDlg" Control_="Back" Event="[Text_Next]" Argument="[AI_Text_Next_Orig]" Condition="AI_INSTALL" Ordering="1" Options="2"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent">
<ROW Action="AI_DOWNGRADE" Type="19" Target="4010"/>
<ROW Action="AI_DpiContentScale" Type="1" Source="aicustact.dll" Target="DpiContentScale"/>
<ROW Action="AI_InstallModeCheck" Type="1" Source="aicustact.dll" Target="UpdateInstallMode" WithoutSeq="true"/>
<ROW Action="AI_PREPARE_UPGRADE" Type="65" Source="aicustact.dll" Target="PrepareUpgrade"/>
<ROW Action="AI_RESTORE_LOCATION" Type="65" Source="aicustact.dll" Target="RestoreLocation"/>
<ROW Action="AI_ResolveKnownFolders" Type="1" Source="aicustact.dll" Target="AI_ResolveKnownFolders"/>
<ROW Action="AI_ResolveLocalizedCredentials" Type="1" Source="aicustact.dll" Target="GetLocalizedCredentials"/>
<ROW Action="AI_SHOW_LOG" Type="65" Source="aicustact.dll" Target="LaunchLogFile" WithoutSeq="true"/>
<ROW Action="AI_STORE_LOCATION" Type="51" Source="ARPINSTALLLOCATION" Target="[APPDIR]"/>
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]"/>
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
<ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
<ROW Name="zt1icon.exe" SourcePath="..\..\..\ZeroTierUI\zt1icon.ico" Index="0"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent">
<ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel &lt;&gt; 5)" Sequence="210"/>
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=&quot;&quot;" Sequence="749"/>
<ROW Action="AI_STORE_LOCATION" Condition="(Not Installed) OR REINSTALL" Sequence="1501"/>
<ROW Action="AI_PREPARE_UPGRADE" Condition="AI_UPGRADE=&quot;No&quot; AND (Not Installed)" Sequence="1399"/>
<ROW Action="AI_ResolveKnownFolders" Sequence="52"/>
<ROW Action="AI_ResolveLocalizedCredentials" Sequence="51"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=&quot;&quot;" Sequence="749"/>
<ROW Action="AI_ResolveKnownFolders" Sequence="53"/>
<ROW Action="AI_ResolveLocalizedCredentials" Sequence="52"/>
<ROW Action="AI_DpiContentScale" Sequence="51"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiLaunchConditionsComponent">
<ROW Condition="( Version9X OR ( NOT VersionNT64 ) OR ( VersionNT64 AND ((VersionNT64 &lt;&gt; 502) OR (((VersionNT64 = 502) AND (ServicePackLevel &gt;= 1)) OR (MsiNTProductType &lt;&gt; 1))) AND ((VersionNT64 &lt;&gt; 502) OR (((VersionNT64 = 502) AND (ServicePackLevel &lt;&gt; 1)) OR (MsiNTProductType &lt;&gt; 1))) AND ((VersionNT64 &lt;&gt; 502) OR (((VersionNT64 = 502) AND (ServicePackLevel &lt;&gt; 2)) OR (MsiNTProductType &lt;&gt; 1))) ) )" Description="[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNT64Display]" DescriptionLocId="AI.LaunchCondition.NoSpecificNT64" IsPredefined="true" Builds="DefaultBuild"/>
<ROW Condition="( Version9X OR VersionNT64 OR ( VersionNT AND ((VersionNT &lt;&gt; 500) OR ((VersionNT = 500) AND (ServicePackLevel &gt;= 1))) AND ((VersionNT &lt;&gt; 500) OR ((VersionNT = 500) AND (ServicePackLevel &lt;&gt; 1))) AND ((VersionNT &lt;&gt; 500) OR ((VersionNT = 500) AND (ServicePackLevel &lt;&gt; 2))) AND ((VersionNT &lt;&gt; 500) OR ((VersionNT = 500) AND (ServicePackLevel &lt;&gt; 3))) AND ((VersionNT &lt;&gt; 500) OR ((VersionNT = 500) AND (ServicePackLevel &lt;&gt; 4))) AND (((VersionNT &lt;&gt; 501) OR ((VersionNT = 501) AND (ServicePackLevel &gt;= 1))) OR VersionNT64) AND (((VersionNT &lt;&gt; 501) OR ((VersionNT = 501) AND (ServicePackLevel &lt;&gt; 1))) OR VersionNT64) AND (((VersionNT &lt;&gt; 501) OR ((VersionNT = 501) AND (ServicePackLevel &lt;&gt; 2))) OR VersionNT64) AND (((VersionNT &lt;&gt; 501) OR ((VersionNT = 501) AND (ServicePackLevel &lt;&gt; 3))) OR VersionNT64) ) )" Description="[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNTDisplay]" DescriptionLocId="AI.LaunchCondition.NoSpecificNT" IsPredefined="true" Builds="DefaultBuild"/>
<ROW Condition="(VersionNT &lt;&gt; 400)" Description="[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNT40Display]" DescriptionLocId="AI.LaunchCondition.NoNT40" IsPredefined="true" Builds="DefaultBuild"/>
<ROW Condition="VersionNT" Description="[ProductName] cannot be installed on [WindowsType9XDisplay]" DescriptionLocId="AI.LaunchCondition.No9X" IsPredefined="true" Builds="DefaultBuild"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiRegsComponent">
<ROW Registry="Path" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/>
<ROW Registry="Version" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Version" Value="[ProductVersion]" Component_="ProductInformation"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiThemeComponent">
<ATTRIBUTE name="UsedTheme" value="classic"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiUpgradeComponent">
<ROW UpgradeCode="[|UpgradeCode]" VersionMin="0.0.1" VersionMax="[|ProductVersion]" Attributes="257" ActionProperty="OLDPRODUCTS"/>
<ROW UpgradeCode="[|UpgradeCode]" VersionMin="[|ProductVersion]" Attributes="2" ActionProperty="AI_NEWERPRODUCTFOUND"/>
</COMPONENT>
</DOCUMENT>

View File

@ -1,477 +0,0 @@
/*
bench.c - Demo program to benchmark open-source compression algorithm
Copyright (C) Yann Collet 2012
GPL v2 License
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 2 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You can contact the author at :
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
- LZ4 source repository : http://code.google.com/p/lz4/
*/
//**************************************
// Compiler Options
//**************************************
// Disable some Visual warning messages
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE // VS2005
// Unix Large Files support (>4GB)
#if (defined(__sun__) && (!defined(__LP64__))) // Sun Solaris 32-bits requires specific definitions
# define _LARGEFILE_SOURCE
# define FILE_OFFSET_BITS=64
#elif ! defined(__LP64__) // No point defining Large file for 64 bit
# define _LARGEFILE64_SOURCE
#endif
// S_ISREG & gettimeofday() are not supported by MSVC
#if defined(_MSC_VER)
# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
# define BMK_LEGACY_TIMER 1
#endif
// GCC does not support _rotl outside of Windows
#if !defined(_WIN32)
# define _rotl(x,r) ((x << r) | (x >> (32 - r)))
#endif
//**************************************
// Includes
//**************************************
#include <stdlib.h> // malloc
#include <stdio.h> // fprintf, fopen, ftello64
#include <sys/types.h> // stat64
#include <sys/stat.h> // stat64
// Use ftime() if gettimeofday() is not available on your target
#if defined(BMK_LEGACY_TIMER)
# include <sys/timeb.h> // timeb, ftime
#else
# include <sys/time.h> // gettimeofday
#endif
#include "lz4.h"
#define COMPRESSOR0 LZ4_compress
#include "lz4hc.h"
#define COMPRESSOR1 LZ4_compressHC
#define DEFAULTCOMPRESSOR LZ4_compress
//**************************************
// Basic Types
//**************************************
#if defined(_MSC_VER) // Visual Studio does not support 'stdint' natively
#define BYTE unsigned __int8
#define U16 unsigned __int16
#define U32 unsigned __int32
#define S32 __int32
#define U64 unsigned __int64
#else
#include <stdint.h>
#define BYTE uint8_t
#define U16 uint16_t
#define U32 uint32_t
#define S32 int32_t
#define U64 uint64_t
#endif
//**************************************
// Constants
//**************************************
#define NBLOOPS 3
#define TIMELOOP 2000
#define KNUTH 2654435761U
#define MAX_MEM (1984<<20)
#define DEFAULT_CHUNKSIZE (8<<20)
//**************************************
// Local structures
//**************************************
struct chunkParameters
{
U32 id;
char* inputBuffer;
char* outputBuffer;
int inputSize;
int outputSize;
};
struct compressionParameters
{
int (*compressionFunction)(const char*, char*, int);
int (*decompressionFunction)(const char*, char*, int);
};
//**************************************
// MACRO
//**************************************
#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
//**************************************
// Benchmark Parameters
//**************************************
static int chunkSize = DEFAULT_CHUNKSIZE;
static int nbIterations = NBLOOPS;
static int BMK_pause = 0;
void BMK_SetBlocksize(int bsize)
{
chunkSize = bsize;
DISPLAY("-Using Block Size of %i KB-", chunkSize>>10);
}
void BMK_SetNbIterations(int nbLoops)
{
nbIterations = nbLoops;
DISPLAY("- %i iterations-", nbIterations);
}
void BMK_SetPause()
{
BMK_pause = 1;
}
//*********************************************************
// Private functions
//*********************************************************
#if defined(BMK_LEGACY_TIMER)
static int BMK_GetMilliStart()
{
// Based on Legacy ftime()
// Rolls over every ~ 12.1 days (0x100000/24/60/60)
// Use GetMilliSpan to correct for rollover
struct timeb tb;
int nCount;
ftime( &tb );
nCount = (int) (tb.millitm + (tb.time & 0xfffff) * 1000);
return nCount;
}
#else
static int BMK_GetMilliStart()
{
// Based on newer gettimeofday()
// Use GetMilliSpan to correct for rollover
struct timeval tv;
int nCount;
gettimeofday(&tv, NULL);
nCount = (int) (tv.tv_usec/1000 + (tv.tv_sec & 0xfffff) * 1000);
return nCount;
}
#endif
static int BMK_GetMilliSpan( int nTimeStart )
{
int nSpan = BMK_GetMilliStart() - nTimeStart;
if ( nSpan < 0 )
nSpan += 0x100000 * 1000;
return nSpan;
}
static U32 BMK_checksum_MMH3A (char* buff, U32 length)
{
const BYTE* data = (const BYTE*)buff;
const int nblocks = length >> 2;
U32 h1 = KNUTH;
U32 c1 = 0xcc9e2d51;
U32 c2 = 0x1b873593;
const U32* blocks = (const U32*)(data + nblocks*4);
int i;
for(i = -nblocks; i; i++)
{
U32 k1 = blocks[i];
k1 *= c1;
k1 = _rotl(k1,15);
k1 *= c2;
h1 ^= k1;
h1 = _rotl(h1,13);
h1 = h1*5+0xe6546b64;
}
{
const BYTE* tail = (const BYTE*)(data + nblocks*4);
U32 k1 = 0;
switch(length & 3)
{
case 3: k1 ^= tail[2] << 16;
case 2: k1 ^= tail[1] << 8;
case 1: k1 ^= tail[0];
k1 *= c1; k1 = _rotl(k1,15); k1 *= c2; h1 ^= k1;
};
}
h1 ^= length;
h1 ^= h1 >> 16;
h1 *= 0x85ebca6b;
h1 ^= h1 >> 13;
h1 *= 0xc2b2ae35;
h1 ^= h1 >> 16;
return h1;
}
static size_t BMK_findMaxMem(U64 requiredMem)
{
size_t step = (64U<<20); // 64 MB
BYTE* testmem=NULL;
requiredMem = (((requiredMem >> 25) + 1) << 26);
if (requiredMem > MAX_MEM) requiredMem = MAX_MEM;
requiredMem += 2*step;
while (!testmem)
{
requiredMem -= step;
testmem = malloc ((size_t)requiredMem);
}
free (testmem);
return (size_t) (requiredMem - step);
}
static U64 BMK_GetFileSize(char* infilename)
{
int r;
#if defined(_MSC_VER)
struct _stat64 statbuf;
r = _stat64(infilename, &statbuf);
#else
struct stat statbuf;
r = stat(infilename, &statbuf);
#endif
if (r || !S_ISREG(statbuf.st_mode)) return 0; // No good...
return (U64)statbuf.st_size;
}
//*********************************************************
// Public function
//*********************************************************
int BMK_benchFile(char** fileNamesTable, int nbFiles, int cLevel)
{
int fileIdx=0;
FILE* fileIn;
char* infilename;
U64 largefilesize;
size_t benchedsize;
int nbChunks;
int maxCChunkSize;
size_t readSize;
char* in_buff;
char* out_buff; int out_buff_size;
struct chunkParameters* chunkP;
U32 crcc, crcd=0;
struct compressionParameters compP;
U64 totals = 0;
U64 totalz = 0;
double totalc = 0.;
double totald = 0.;
// Init
switch (cLevel)
{
#ifdef COMPRESSOR0
case 0 : compP.compressionFunction = COMPRESSOR0; break;
#endif
#ifdef COMPRESSOR1
case 1 : compP.compressionFunction = COMPRESSOR1; break;
#endif
default : compP.compressionFunction = DEFAULTCOMPRESSOR;
}
compP.decompressionFunction = LZ4_uncompress;
// Loop for each file
while (fileIdx<nbFiles)
{
// Check file existence
infilename = fileNamesTable[fileIdx++];
fileIn = fopen( infilename, "rb" );
if (fileIn==NULL)
{
DISPLAY( "Pb opening %s\n", infilename);
return 11;
}
// Memory allocation & restrictions
largefilesize = BMK_GetFileSize(infilename);
benchedsize = (size_t) BMK_findMaxMem(largefilesize) / 2;
if ((U64)benchedsize > largefilesize) benchedsize = (size_t)largefilesize;
if (benchedsize < largefilesize)
{
DISPLAY("Not enough memory for '%s' full size; testing %i MB only...\n", infilename, (int)(benchedsize>>20));
}
// Alloc
chunkP = (struct chunkParameters*) malloc(((benchedsize / chunkSize)+1) * sizeof(struct chunkParameters));
in_buff = malloc((size_t )benchedsize);
nbChunks = (int) (benchedsize / chunkSize) + 1;
maxCChunkSize = LZ4_compressBound(chunkSize);
out_buff_size = nbChunks * maxCChunkSize;
out_buff = malloc((size_t )out_buff_size);
if(!in_buff || !out_buff)
{
DISPLAY("\nError: not enough memory!\n");
free(in_buff);
free(out_buff);
fclose(fileIn);
return 12;
}
// Init chunks data
{
int i;
size_t remaining = benchedsize;
char* in = in_buff;
char* out = out_buff;
for (i=0; i<nbChunks; i++)
{
chunkP[i].id = i;
chunkP[i].inputBuffer = in; in += chunkSize;
if ((int)remaining > chunkSize) { chunkP[i].inputSize = chunkSize; remaining -= chunkSize; } else { chunkP[i].inputSize = (int)remaining; remaining = 0; }
chunkP[i].outputBuffer = out; out += maxCChunkSize;
chunkP[i].outputSize = 0;
}
}
// Fill input buffer
DISPLAY("Loading %s... \r", infilename);
readSize = fread(in_buff, 1, benchedsize, fileIn);
fclose(fileIn);
if(readSize != benchedsize)
{
DISPLAY("\nError: problem reading file '%s' !! \n", infilename);
free(in_buff);
free(out_buff);
return 13;
}
// Calculating input Checksum
crcc = BMK_checksum_MMH3A(in_buff, (unsigned int)benchedsize);
// Bench
{
int loopNb, nb_loops, chunkNb;
size_t cSize=0;
int milliTime;
double fastestC = 100000000., fastestD = 100000000.;
double ratio=0.;
DISPLAY("\r%79s\r", "");
for (loopNb = 1; loopNb <= nbIterations; loopNb++)
{
// Compression
DISPLAY("%1i-%-14.14s : %9i ->\r", loopNb, infilename, (int)benchedsize);
{ size_t i; for (i=0; i<benchedsize; i++) out_buff[i]=(char)i; } // warmimg up memory
nb_loops = 0;
milliTime = BMK_GetMilliStart();
while(BMK_GetMilliStart() == milliTime);
milliTime = BMK_GetMilliStart();
while(BMK_GetMilliSpan(milliTime) < TIMELOOP)
{
for (chunkNb=0; chunkNb<nbChunks; chunkNb++)
chunkP[chunkNb].outputSize = compP.compressionFunction(chunkP[chunkNb].inputBuffer, chunkP[chunkNb].outputBuffer, chunkP[chunkNb].inputSize);
nb_loops++;
}
milliTime = BMK_GetMilliSpan(milliTime);
if ((double)milliTime < fastestC*nb_loops) fastestC = (double)milliTime/nb_loops;
cSize=0; for (chunkNb=0; chunkNb<nbChunks; chunkNb++) cSize += chunkP[chunkNb].outputSize;
ratio = (double)cSize/(double)benchedsize*100.;
DISPLAY("%1i-%-14.14s : %9i -> %9i (%5.2f%%),%7.1f MB/s\r", loopNb, infilename, (int)benchedsize, (int)cSize, ratio, (double)benchedsize / fastestC / 1000.);
// Decompression
{ size_t i; for (i=0; i<benchedsize; i++) in_buff[i]=0; } // zeroing area, for CRC checking
nb_loops = 0;
milliTime = BMK_GetMilliStart();
while(BMK_GetMilliStart() == milliTime);
milliTime = BMK_GetMilliStart();
while(BMK_GetMilliSpan(milliTime) < TIMELOOP)
{
for (chunkNb=0; chunkNb<nbChunks; chunkNb++)
chunkP[chunkNb].outputSize = LZ4_uncompress(chunkP[chunkNb].outputBuffer, chunkP[chunkNb].inputBuffer, chunkP[chunkNb].inputSize);
//chunkP[chunkNb].inputSize = LZ4_uncompress_unknownOutputSize(chunkP[chunkNb].outputBuffer, chunkP[chunkNb].inputBuffer, chunkP[chunkNb].outputSize, chunkSize);
nb_loops++;
}
milliTime = BMK_GetMilliSpan(milliTime);
if ((double)milliTime < fastestD*nb_loops) fastestD = (double)milliTime/nb_loops;
DISPLAY("%1i-%-14.14s : %9i -> %9i (%5.2f%%),%7.1f MB/s ,%7.1f MB/s\r", loopNb, infilename, (int)benchedsize, (int)cSize, ratio, (double)benchedsize / fastestC / 1000., (double)benchedsize / fastestD / 1000.);
// CRC Checking
crcd = BMK_checksum_MMH3A(in_buff, (unsigned int)benchedsize);
if (crcc!=crcd) { DISPLAY("\n!!! WARNING !!! %14s : Invalid Checksum : %x != %x\n", infilename, (unsigned)crcc, (unsigned)crcd); break; }
}
if (crcc==crcd)
{
if (ratio<100.)
DISPLAY("%-16.16s : %9i -> %9i (%5.2f%%),%7.1f MB/s ,%7.1f MB/s\n", infilename, (int)benchedsize, (int)cSize, ratio, (double)benchedsize / fastestC / 1000., (double)benchedsize / fastestD / 1000.);
else
DISPLAY("%-16.16s : %9i -> %9i (%5.1f%%),%7.1f MB/s ,%7.1f MB/s \n", infilename, (int)benchedsize, (int)cSize, ratio, (double)benchedsize / fastestC / 1000., (double)benchedsize / fastestD / 1000.);
}
totals += benchedsize;
totalz += cSize;
totalc += fastestC;
totald += fastestD;
}
free(in_buff);
free(out_buff);
free(chunkP);
}
if (nbFiles > 1)
printf("%-16.16s :%10llu ->%10llu (%5.2f%%), %6.1f MB/s , %6.1f MB/s\n", " TOTAL", (long long unsigned int)totals, (long long unsigned int)totalz, (double)totalz/(double)totals*100., (double)totals/totalc/1000., (double)totals/totald/1000.);
if (BMK_pause) { printf("press enter...\n"); getchar(); }
return 0;
}

View File

@ -1,41 +0,0 @@
/*
bench.h - Demo program to benchmark open-source compression algorithm
Copyright (C) Yann Collet 2012
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 2 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You can contact the author at :
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
- LZ4 source repository : http://code.google.com/p/lz4/
*/
#pragma once
#if defined (__cplusplus)
extern "C" {
#endif
int BMK_benchFile(char** fileNamesTable, int nbFiles, int cLevel);
// Parameters
void BMK_SetBlocksize(int bsize);
void BMK_SetNbIterations(int nbLoops);
void BMK_SetPause();
#if defined (__cplusplus)
}
#endif

View File

@ -1,227 +0,0 @@
/*
fuzzer.c - Fuzzer test tool for LZ4
Copyright (C) Andrew Mahone - Yann Collet 2012
Original code by Andrew Mahone / Modified by Yann Collet
GPL v2 License
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 2 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You can contact the author at :
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
- LZ4 source repository : http://code.google.com/p/lz4/
*/
//**************************************
// Remove Visual warning messages
//**************************************
#define _CRT_SECURE_NO_WARNINGS // fgets
//**************************************
// Includes
//**************************************
#include <stdlib.h>
#include <stdio.h> // fgets, sscanf
#include <sys/timeb.h> // timeb
#include "lz4.h"
//**************************************
// Constants
//**************************************
#define NB_ATTEMPTS (1<<18)
#define LEN ((1<<15))
#define SEQ_POW 2
#define NUM_SEQ (1 << SEQ_POW)
#define SEQ_MSK ((NUM_SEQ) - 1)
#define MOD_SEQ(x) ((((x) >> 8) & 255) == 0)
#define NEW_SEQ(x) ((((x) >> 10) %10) == 0)
#define PAGE_SIZE 4096
#define ROUND_PAGE(x) (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
#define PRIME1 2654435761U
#define PRIME2 2246822519U
#define PRIME3 3266489917U
//*********************************************************
// Functions
//*********************************************************
static int FUZ_GetMilliStart()
{
struct timeb tb;
int nCount;
ftime( &tb );
nCount = (int) (tb.millitm + (tb.time & 0xfffff) * 1000);
return nCount;
}
static int FUZ_GetMilliSpan( int nTimeStart )
{
int nSpan = FUZ_GetMilliStart() - nTimeStart;
if ( nSpan < 0 )
nSpan += 0x100000 * 1000;
return nSpan;
}
unsigned int FUZ_rand(unsigned int* src)
{
*src = ((*src) * PRIME1) + PRIME2;
return *src;
}
int test_canary(unsigned char *buf) {
int i;
for (i = 0; i < 2048; i++)
if (buf[i] != buf[i + 2048])
return 0;
return 1;
}
int FUZ_SecurityTest()
{
char* output;
char* input;
int i, r;
printf("Starting security tests...");
input = (char*) malloc (20<<20);
output = (char*) malloc (20<<20);
input[0] = 0x0F;
input[1] = 0x00;
input[2] = 0x00;
for(i = 3; i < 16840000; i++)
input[i] = 0xff;
r = LZ4_uncompress(input, output, 20<<20);
free(input);
free(output);
printf(" Completed (r=%i)\n",r);
return 0;
}
//int main(int argc, char *argv[]) {
int main() {
unsigned long long bytes = 0;
unsigned long long cbytes = 0;
unsigned char buf[LEN];
unsigned char testOut[LEN+1];
# define FUZ_max LZ4_COMPRESSBOUND(LEN)
# define FUZ_avail ROUND_PAGE(FUZ_max)
const int off_full = FUZ_avail - FUZ_max;
unsigned char cbuf[FUZ_avail + PAGE_SIZE];
unsigned int seed, cur_seq=PRIME3, seeds[NUM_SEQ], timestamp=FUZ_GetMilliStart();
int i, j, k, ret, len;
char userInput[30] = {0};
printf("starting LZ4 fuzzer\n");
printf("Select an Initialisation number (default : random) : ");
fflush(stdout);
if ( fgets(userInput, sizeof userInput, stdin) )
{
if ( sscanf(userInput, "%d", &seed) == 1 ) {}
else seed = FUZ_GetMilliSpan(timestamp);
}
printf("Seed = %u\n", seed);
FUZ_SecurityTest();
for (i = 0; i < 2048; i++)
cbuf[FUZ_avail + i] = cbuf[FUZ_avail + 2048 + i] = FUZ_rand(&seed) >> 16;
for (i = 0; i < NB_ATTEMPTS; i++)
{
printf("\r%7i /%7i\r", i, NB_ATTEMPTS);
FUZ_rand(&seed);
for (j = 0; j < NUM_SEQ; j++) {
seeds[j] = FUZ_rand(&seed) << 8;
seeds[j] ^= (FUZ_rand(&seed) >> 8) & 65535;
}
for (j = 0; j < LEN; j++) {
k = FUZ_rand(&seed);
if (j == 0 || NEW_SEQ(k))
cur_seq = seeds[(FUZ_rand(&seed) >> 16) & SEQ_MSK];
if (MOD_SEQ(k)) {
k = (FUZ_rand(&seed) >> 16) & SEQ_MSK;
seeds[k] = FUZ_rand(&seed) << 8;
seeds[k] ^= (FUZ_rand(&seed) >> 8) & 65535;
}
buf[j] = FUZ_rand(&cur_seq) >> 16;
}
// Test compression
ret = LZ4_compress_limitedOutput((const char*)buf, (char*)&cbuf[off_full], LEN, FUZ_max);
if (ret == 0) { printf("compression failed despite sufficient space: seed %u, len %d\n", seed, LEN); goto _output_error; }
len = ret;
// Test decoding with output size being exactly what's necessary => must work
ret = LZ4_uncompress((char*)&cbuf[off_full], (char*)testOut, LEN);
if (ret<0) { printf("decompression failed despite correct space: seed %u, len %d\n", seed, LEN); goto _output_error; }
// Test decoding with one byte missing => must fail
ret = LZ4_uncompress((char*)&cbuf[off_full], (char*)testOut, LEN-1);
if (ret>=0) { printf("decompression should have failed, due to Output Size being too small : seed %u, len %d\n", seed, LEN); goto _output_error; }
// Test decoding with one byte too much => must fail
ret = LZ4_uncompress((char*)&cbuf[off_full], (char*)testOut, LEN+1);
if (ret>=0) { printf("decompression should have failed, due to Output Size being too large : seed %u, len %d\n", seed, LEN); goto _output_error; }
// Test decoding with enough output size => must work
ret = LZ4_uncompress_unknownOutputSize((char*)&cbuf[off_full], (char*)testOut, len, LEN+1);
if (ret<0) { printf("decompression failed despite sufficient space: seed %u, len %d\n", seed, LEN); goto _output_error; }
// Test decoding with output size being exactly what's necessary => must work
ret = LZ4_uncompress_unknownOutputSize((char*)&cbuf[off_full], (char*)testOut, len, LEN);
if (ret<0) { printf("decompression failed despite sufficient space: seed %u, len %d\n", seed, LEN); goto _output_error; }
// Test decoding with output size being one byte too short => must fail
ret = LZ4_uncompress_unknownOutputSize((char*)&cbuf[off_full], (char*)testOut, len, LEN-1);
if (ret>=0) { printf("decompression should have failed, due to Output Size being too small : seed %u, len %d\n", seed, LEN); goto _output_error; }
// Test decoding with input size being one byte too short => must fail
ret = LZ4_uncompress_unknownOutputSize((char*)&cbuf[off_full], (char*)testOut, len-1, LEN);
if (ret>=0) { printf("decompression should have failed, due to input size being too small : seed %u, len %d\n", seed, LEN); goto _output_error; }
// Test decoding with input size being one byte too large => must fail
ret = LZ4_uncompress_unknownOutputSize((char*)&cbuf[off_full], (char*)testOut, len+1, LEN);
if (ret>=0) { printf("decompression should have failed, due to input size being too large : seed %u, len %d\n", seed, LEN); goto _output_error; }
// Test compression with output size being exactly what's necessary (should work)
ret = LZ4_compress_limitedOutput((const char*)buf, (char*)&cbuf[FUZ_avail-len], LEN, len);
if (!test_canary(&cbuf[FUZ_avail])) { printf("compression overran output buffer: seed %u, len %d, olen %d\n", seed, LEN, len); goto _output_error; }
if (ret == 0) { printf("compression failed despite sufficient space: seed %u, len %d\n", seed, LEN); goto _output_error; }
// Test compression with just one missing byte into output buffer => must fail
ret = LZ4_compress_limitedOutput((const char*)buf, (char*)&cbuf[FUZ_avail-(len-1)], LEN, len-1);
if (ret) { printf("compression overran output buffer: seed %u, len %d, olen %d => ret %d", seed, LEN, len-1, ret); goto _output_error; }
if (!test_canary(&cbuf[FUZ_avail])) { printf("compression overran output buffer: seed %u, len %d, olen %d", seed, LEN, len-1); goto _output_error; }
bytes += LEN;
cbytes += len;
}
printf("all tests completed successfully \n");
printf("compression ratio: %0.3f%%\n", (double)cbytes/bytes*100);
getchar();
return 0;
_output_error:
getchar();
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/*
LZ4 - Fast LZ compression algorithm
Header File
Copyright (C) 2011-2012, Yann Collet.
Copyright (C) 2011-2013, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
@ -42,7 +42,7 @@ extern "C" {
// Compiler Options
//**************************************
#if defined(_MSC_VER) && !defined(__cplusplus) // Visual Studio
# define inline __inline // Visual is not C99, but supports some kind of inline
# define inline __inline // Visual C is not C99, but supports some kind of inline
#endif
@ -50,78 +50,155 @@ extern "C" {
// Simple Functions
//****************************
int LZ4_compress (const char* source, char* dest, int isize);
int LZ4_uncompress (const char* source, char* dest, int osize);
int LZ4_compress (const char* source, char* dest, int inputSize);
int LZ4_decompress_safe (const char* source, char* dest, int inputSize, int maxOutputSize);
/*
LZ4_compress() :
Compresses 'isize' bytes from 'source' into 'dest'.
Compresses 'inputSize' bytes from 'source' into 'dest'.
Destination buffer must be already allocated,
and must be sized to handle worst cases situations (input data not compressible)
Worst case size evaluation is provided by function LZ4_compressBound()
isize : is the input size. Max supported value is ~1.9GB
inputSize : Max supported value is LZ4_MAX_INPUT_VALUE
return : the number of bytes written in buffer dest
or 0 if the compression fails
LZ4_uncompress() :
osize : is the output size, therefore the original size
return : the number of bytes read in the source buffer
If the source stream is malformed, the function will stop decoding and return a negative result, indicating the byte position of the faulty instruction
This function never writes outside of provided buffers, and never modifies input buffer.
note : destination buffer must be already allocated.
its size must be a minimum of 'osize' bytes.
LZ4_decompress_safe() :
maxOutputSize : is the size of the destination buffer (which must be already allocated)
return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize)
If the source stream is detected malformed, the function will stop decoding and return a negative result.
This function is protected against buffer overflow exploits (never writes outside of output buffer, and never reads outside of input buffer). Therefore, it is protected against malicious data packets
*/
//****************************
// Advanced Functions
//****************************
static inline int LZ4_compressBound(int isize) { return ((isize) + ((isize)/255) + 16); }
#define LZ4_COMPRESSBOUND( isize) ((isize) + ((isize)/255) + 16)
#define LZ4_MAX_INPUT_SIZE 0x7E000000 // 2 113 929 216 bytes
#define LZ4_COMPRESSBOUND(isize) ((unsigned int)(isize) > (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
static inline int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); }
/*
LZ4_compressBound() :
Provides the maximum size that LZ4 may output in a "worst case" scenario (input data not compressible)
primarily useful for memory allocation of output buffer.
inline function is recommended for the general case,
but macro is also provided when results need to be evaluated at compile time (such as table size allocation).
inline function is recommended for the general case,
macro is also provided when result needs to be evaluated at compilation (such as stack memory allocation).
isize : is the input size. Max supported value is ~1.9GB
isize : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE
return : maximum output size in a "worst case" scenario
note : this function is limited by "int" range (2^31-1)
or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE)
*/
int LZ4_compress_limitedOutput (const char* source, char* dest, int isize, int maxOutputSize);
int LZ4_compress_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize);
/*
LZ4_compress_limitedOutput() :
Compress 'isize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'.
Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'.
If it cannot achieve it, compression will stop, and result of the function will be zero.
This function never writes outside of provided output buffer.
isize : is the input size. Max supported value is ~1.9GB
inputSize : Max supported value is LZ4_MAX_INPUT_VALUE
maxOutputSize : is the size of the destination buffer (which must be already allocated)
return : the number of bytes written in buffer 'dest'
or 0 if the compression fails
*/
int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize);
int LZ4_decompress_fast (const char* source, char* dest, int outputSize);
/*
LZ4_uncompress_unknownOutputSize() :
isize : is the input size, therefore the compressed size
maxOutputSize : is the size of the destination buffer (which must be already allocated)
return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize)
If the source stream is malformed, the function will stop decoding and return a negative result, indicating the byte position of the faulty instruction
This function never writes beyond dest + maxOutputSize, and is therefore protected against malicious data packets
note : Destination buffer must be already allocated.
This version is slightly slower than LZ4_uncompress()
LZ4_decompress_fast() :
outputSize : is the original (uncompressed) size
return : the number of bytes read from the source buffer (in other words, the compressed size)
If the source stream is malformed, the function will stop decoding and return a negative result.
note : This function is a bit faster than LZ4_decompress_safe()
This function never writes outside of output buffers, but may read beyond input buffer in case of malicious data packet.
Use this function preferably into a trusted environment (data to decode comes from a trusted source).
Destination buffer must be already allocated. Its size must be a minimum of 'outputSize' bytes.
*/
int LZ4_decompress_safe_partial (const char* source, char* dest, int inputSize, int targetOutputSize, int maxOutputSize);
/*
LZ4_decompress_safe_partial() :
This function decompress a compressed block of size 'inputSize' at position 'source'
into output buffer 'dest' of size 'maxOutputSize'.
The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached,
reducing decompression time.
return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize)
Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller.
Always control how many bytes were decoded.
If the source stream is detected malformed, the function will stop decoding and return a negative result.
This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets
*/
//****************************
// Stream Functions
//****************************
void* LZ4_create (const char* inputBuffer);
int LZ4_compress_continue (void* LZ4_Data, const char* source, char* dest, int inputSize);
int LZ4_compress_limitedOutput_continue (void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize);
char* LZ4_slideInputBuffer (void* LZ4_Data);
int LZ4_free (void* LZ4_Data);
/*
These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks.
In order to achieve this, it is necessary to start creating the LZ4 Data Structure, thanks to the function :
void* LZ4_create (const char* inputBuffer);
The result of the function is the (void*) pointer on the LZ4 Data Structure.
This pointer will be needed in all other functions.
If the pointer returned is NULL, then the allocation has failed, and compression must be aborted.
The only parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer.
The input buffer must be already allocated, and size at least 192KB.
'inputBuffer' will also be the 'const char* source' of the first block.
All blocks are expected to lay next to each other within the input buffer, starting from 'inputBuffer'.
To compress each block, use either LZ4_compress_continue() or LZ4_compress_limitedOutput_continue().
Their behavior are identical to LZ4_compress() or LZ4_compress_limitedOutput(),
but require the LZ4 Data Structure as their first argument, and check that each block starts right after the previous one.
If next block does not begin immediately after the previous one, the compression will fail (return 0).
When it's no longer possible to lay the next block after the previous one (not enough space left into input buffer), a call to :
char* LZ4_slideInputBuffer(void* LZ4_Data);
must be performed. It will typically copy the latest 64KB of input at the beginning of input buffer.
Note that, for this function to work properly, minimum size of an input buffer must be 192KB.
==> The memory position where the next input data block must start is provided as the result of the function.
Compression can then resume, using LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(), as usual.
When compression is completed, a call to LZ4_free() will release the memory used by the LZ4 Data Structure.
*/
int LZ4_decompress_safe_withPrefix64k (const char* source, char* dest, int inputSize, int maxOutputSize);
int LZ4_decompress_fast_withPrefix64k (const char* source, char* dest, int outputSize);
/*
*_withPrefix64k() :
These decoding functions work the same as their "normal name" versions,
but can use up to 64KB of data in front of 'char* dest'.
These functions are necessary to decode inter-dependant blocks.
*/
//****************************
// Obsolete Functions
//****************************
static inline int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); }
static inline int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); }
/*
These functions are deprecated and should no longer be used.
They are provided here for compatibility with existing user programs.
*/
#if defined (__cplusplus)
}

View File

@ -1,121 +0,0 @@
LZ4 Format Description
Last revised: 2012-02-27
Author : Y. Collet
This small specification intents to provide enough information
to anyone willing to produce LZ4-compatible compressed streams
using any programming language.
LZ4 is an LZ77-type compressor with a fixed, byte-oriented encoding.
The most important design principle behind LZ4 is simplicity.
It helps to create an easy to read and maintain source code.
It also helps later on for optimisations, compactness, and speed.
There is no entropy encoder backend nor framing layer.
The latter is assumed to be handled by other parts of the system.
This document only describes the format,
not how the LZ4 compressor nor decompressor actually work.
The correctness of the decompressor should not depend
on implementation details of the compressor, and vice versa.
-- Compressed stream format --
An LZ4 compressed stream is composed of sequences.
Schematically, a sequence is a suite of literals, followed by a match copy.
Each sequence starts with a token.
The token is a one byte value, separated into two 4-bits fields.
Therefore each field ranges from 0 to 15.
The first field uses the 4 high-bits of the token.
It provides the length of literals to follow.
(Note : a literal is a not-compressed byte).
If the field value is 0, then there is no literal.
If it is 15, then we need to add some more bytes to indicate the full length.
Each additionnal byte then represent a value from 0 to 255,
which is added to the previous value to produce a total length.
When the byte value is 255, another byte is output.
There can be any number of bytes following the token. There is no "size limit".
(Sidenote this is why a not-compressible input stream is expanded by 0.4%).
Example 1 : A length of 48 will be represented as :
- 15 : value for the 4-bits High field
- 33 : (=48-15) remaining length to reach 48
Example 2 : A length of 280 will be represented as :
- 15 : value for the 4-bits High field
- 255 : following byte is maxed, since 280-15 >= 255
- 10 : (=280 - 15 - 255) ) remaining length to reach 280
Example 3 : A length of 15 will be represented as :
- 15 : value for the 4-bits High field
- 0 : (=15-15) yes, the zero must be output
Following the token and optional length bytes, are the literals themselves.
They are exactly as numerous as previously decoded (length of literals).
It's possible that there are zero literal.
Following the literals is the match copy operation.
It starts by the offset.
This is a 2 bytes value, in little endian format :
the lower byte is the first one in the stream.
The offset represents the position of the match to be copied from.
1 means "current position - 1 byte".
The maximum offset value is 65535, 65536 cannot be coded.
Note that 0 is an invalid value, not used.
Then we need to extract the match length.
For this, we use the second token field, the low 4-bits.
Value, obviously, ranges from 0 to 15.
However here, 0 means that the copy operation will be minimal.
The minimum length of a match, called minmatch, is 4.
As a consequence, a 0 value means 4 bytes, and a value of 15 means 19+ bytes.
Similar to literal length, on reaching the highest possible value (15),
we output additional bytes, one at a time, with values ranging from 0 to 255.
They are added to total to provide the final match length.
A 255 value means there is another byte to read and add.
There is no limit to the number of optional bytes that can be output this way.
(This points towards a maximum achievable compression ratio of ~250).
With the offset and the matchlength,
the decoder can now proceed to copy the data from the already decoded buffer.
On decoding the matchlength, we reach the end of the compressed sequence,
and therefore start another one.
-- Parsing restrictions --
There are specific parsing rules to respect in order to remain compatible
with assumptions made by the decoder :
1) The last 5 bytes are always literals
2) The last match must start at least 12 bytes before end of stream
Consequently, a file with less than 13 bytes cannot be compressed.
These rules are in place to ensure that the decoder
will never read beyond the input buffer, nor write beyond the output buffer.
Note that the last sequence is also incomplete,
and stops right after literals.
-- Additional notes --
There is no assumption nor limits to the way the compressor
searches and selects matches within the source stream.
It could be a fast scan, a multi-probe, a full search using BST,
standard hash chains or MMC, well whatever.
Advanced parsing strategies can also be implemented, such as lazy match,
or full optimal parsing.
All these trade-off offer distinctive speed/memory/compression advantages.
Whatever the method used by the compressor, its result will be decodable
by any LZ4 decoder if it follows the format specification described above.

View File

@ -1,402 +0,0 @@
/*
LZ4Demo - Demo CLI program using LZ4 compression
Copyright (C) Yann Collet 2011-2012
GPL v2 License
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 2 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You can contact the author at :
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
- LZ4 source repository : http://code.google.com/p/lz4/
*/
/*
Note : this is *only* a demo program, an example to show how LZ4 can be used.
It is not considered part of LZ4 compression library.
The license of LZ4 is BSD.
The license of the demo program is GPL.
*/
//**************************************
// Compiler Options
//**************************************
// Disable some Visual warning messages
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE // VS2005
//****************************
// Includes
//****************************
#include <stdio.h> // fprintf, fopen, fread, _fileno(?)
#include <stdlib.h> // malloc
#include <string.h> // strcmp
#include <time.h> // clock
#ifdef _WIN32
#include <io.h> // _setmode
#include <fcntl.h> // _O_BINARY
#endif
#include "lz4.h"
#include "lz4hc.h"
#include "bench.h"
//**************************************
// Compiler-specific functions
//**************************************
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
#if defined(_MSC_VER) // Visual Studio
#define swap32 _byteswap_ulong
#elif GCC_VERSION >= 403
#define swap32 __builtin_bswap32
#else
static inline unsigned int swap32(unsigned int x) {
return ((x << 24) & 0xff000000 ) |
((x << 8) & 0x00ff0000 ) |
((x >> 8) & 0x0000ff00 ) |
((x >> 24) & 0x000000ff );
}
#endif
//****************************
// Constants
//****************************
#define COMPRESSOR_NAME "Compression CLI using LZ4 algorithm"
#define COMPRESSOR_VERSION ""
#define COMPILED __DATE__
#define AUTHOR "Yann Collet"
#define EXTENSION ".lz4"
#define WELCOME_MESSAGE "*** %s %s, by %s (%s) ***\n", COMPRESSOR_NAME, COMPRESSOR_VERSION, AUTHOR, COMPILED
#define CHUNKSIZE (8<<20) // 8 MB
#define CACHELINE 64
#define ARCHIVE_MAGICNUMBER 0x184C2102
#define ARCHIVE_MAGICNUMBER_SIZE 4
//**************************************
// Architecture Macros
//**************************************
static const int one = 1;
#define CPU_LITTLE_ENDIAN (*(char*)(&one))
#define CPU_BIG_ENDIAN (!CPU_LITTLE_ENDIAN)
#define LITTLE_ENDIAN32(i) if (CPU_BIG_ENDIAN) { i = swap32(i); }
//**************************************
// Macros
//**************************************
#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
//****************************
// Functions
//****************************
int usage(char* exename)
{
DISPLAY( "Usage :\n");
DISPLAY( " %s [arg] input output\n", exename);
DISPLAY( "Arguments :\n");
DISPLAY( " -c0: Fast compression (default) \n");
DISPLAY( " -c1: High compression \n");
DISPLAY( " -d : decompression \n");
DISPLAY( " -b#: Benchmark files, using # compression level\n");
DISPLAY( " -t : check compressed file \n");
DISPLAY( " -h : help (this text)\n");
DISPLAY( "input : can be 'stdin' (pipe) or a filename\n");
DISPLAY( "output : can be 'stdout'(pipe) or a filename or 'null'\n");
return 0;
}
int badusage(char* exename)
{
DISPLAY("Wrong parameters\n");
usage(exename);
return 0;
}
int get_fileHandle(char* input_filename, char* output_filename, FILE** pfinput, FILE** pfoutput)
{
char stdinmark[] = "stdin";
char stdoutmark[] = "stdout";
if (!strcmp (input_filename, stdinmark)) {
DISPLAY( "Using stdin for input\n");
*pfinput = stdin;
#ifdef _WIN32 // Need to set stdin/stdout to binary mode specifically for windows
_setmode( _fileno( stdin ), _O_BINARY );
#endif
} else {
*pfinput = fopen( input_filename, "rb" );
}
if (!strcmp (output_filename, stdoutmark)) {
DISPLAY( "Using stdout for output\n");
*pfoutput = stdout;
#ifdef _WIN32 // Need to set stdin/stdout to binary mode specifically for windows
_setmode( _fileno( stdout ), _O_BINARY );
#endif
} else {
*pfoutput = fopen( output_filename, "wb" );
}
if ( *pfinput==0 ) { DISPLAY( "Pb opening %s\n", input_filename); return 2; }
if ( *pfoutput==0) { DISPLAY( "Pb opening %s\n", output_filename); return 3; }
return 0;
}
int compress_file(char* input_filename, char* output_filename, int compressionlevel)
{
int (*compressionFunction)(const char*, char*, int);
unsigned long long filesize = 0;
unsigned long long compressedfilesize = ARCHIVE_MAGICNUMBER_SIZE;
unsigned int u32var;
char* in_buff;
char* out_buff;
FILE* finput;
FILE* foutput;
int r;
int displayLevel = (compressionlevel>0);
clock_t start, end;
size_t sizeCheck;
// Init
switch (compressionlevel)
{
case 0 : compressionFunction = LZ4_compress; break;
case 1 : compressionFunction = LZ4_compressHC; break;
default : compressionFunction = LZ4_compress;
}
start = clock();
r = get_fileHandle(input_filename, output_filename, &finput, &foutput);
if (r) return r;
// Allocate Memory
in_buff = (char*)malloc(CHUNKSIZE);
out_buff = (char*)malloc(LZ4_compressBound(CHUNKSIZE));
if (!in_buff || !out_buff) { DISPLAY("Allocation error : not enough memory\n"); return 8; }
// Write Archive Header
u32var = ARCHIVE_MAGICNUMBER;
LITTLE_ENDIAN32(u32var);
*(unsigned int*)out_buff = u32var;
sizeCheck = fwrite(out_buff, 1, ARCHIVE_MAGICNUMBER_SIZE, foutput);
if (sizeCheck!=ARCHIVE_MAGICNUMBER_SIZE) { DISPLAY("write error\n"); return 10; }
// Main Loop
while (1)
{
int outSize;
// Read Block
int inSize = (int) fread(in_buff, (size_t)1, (size_t)CHUNKSIZE, finput);
if( inSize<=0 ) break;
filesize += inSize;
if (displayLevel) DISPLAY("Read : %i MB \r", (int)(filesize>>20));
// Compress Block
outSize = compressionFunction(in_buff, out_buff+4, inSize);
compressedfilesize += outSize+4;
if (displayLevel) DISPLAY("Read : %i MB ==> %.2f%%\r", (int)(filesize>>20), (double)compressedfilesize/filesize*100);
// Write Block
LITTLE_ENDIAN32(outSize);
* (unsigned int*) out_buff = outSize;
LITTLE_ENDIAN32(outSize);
sizeCheck = fwrite(out_buff, 1, outSize+4, foutput);
if (sizeCheck!=(size_t)(outSize+4)) { DISPLAY("write error\n"); return 11; }
}
// Status
end = clock();
DISPLAY( "Compressed %llu bytes into %llu bytes ==> %.2f%%\n",
(unsigned long long) filesize, (unsigned long long) compressedfilesize, (double)compressedfilesize/filesize*100);
{
double seconds = (double)(end - start)/CLOCKS_PER_SEC;
DISPLAY( "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);
}
// Close & Free
free(in_buff);
free(out_buff);
fclose(finput);
fclose(foutput);
return 0;
}
int decode_file(char* input_filename, char* output_filename)
{
unsigned long long filesize = 0;
char* in_buff;
char* out_buff;
size_t uselessRet;
int sinkint;
unsigned int chunkSize;
FILE* finput;
FILE* foutput;
clock_t start, end;
int r;
size_t sizeCheck;
// Init
start = clock();
r = get_fileHandle(input_filename, output_filename, &finput, &foutput);
if (r) return r;
// Allocate Memory
in_buff = (char*)malloc(LZ4_compressBound(CHUNKSIZE));
out_buff = (char*)malloc(CHUNKSIZE);
if (!in_buff || !out_buff) { DISPLAY("Allocation error : not enough memory\n"); return 7; }
// Check Archive Header
chunkSize = 0;
uselessRet = fread(&chunkSize, 1, ARCHIVE_MAGICNUMBER_SIZE, finput);
LITTLE_ENDIAN32(chunkSize);
if (chunkSize != ARCHIVE_MAGICNUMBER) { DISPLAY("Unrecognized header : file cannot be decoded\n"); return 6; }
// Main Loop
while (1)
{
// Block Size
uselessRet = fread(&chunkSize, 1, 4, finput);
if( uselessRet==0 ) break; // Nothing to read : file read is completed
LITTLE_ENDIAN32(chunkSize);
if (chunkSize == ARCHIVE_MAGICNUMBER)
continue; // appended compressed stream
// Read Block
uselessRet = fread(in_buff, 1, chunkSize, finput);
// Decode Block
sinkint = LZ4_uncompress_unknownOutputSize(in_buff, out_buff, chunkSize, CHUNKSIZE);
if (sinkint < 0) { DISPLAY("Decoding Failed ! Corrupted input !\n"); return 9; }
filesize += sinkint;
// Write Block
sizeCheck = fwrite(out_buff, 1, sinkint, foutput);
if (sizeCheck != (size_t)sinkint) { DISPLAY("write error\n"); return 12; }
}
// Status
end = clock();
DISPLAY( "Successfully decoded %llu bytes \n", (unsigned long long)filesize);
{
double seconds = (double)(end - start)/CLOCKS_PER_SEC;
DISPLAY( "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);
}
// Close & Free
free(in_buff);
free(out_buff);
fclose(finput);
fclose(foutput);
return 0;
}
int main(int argc, char** argv)
{
int i,
cLevel=0,
decode=0,
bench=0,
filenamesStart=2;
char* exename=argv[0];
char* input_filename=0;
char* output_filename=0;
#ifdef _WIN32
char nulmark[] = "nul";
#else
char nulmark[] = "/dev/null";
#endif
char nullinput[] = "null";
// Welcome message
DISPLAY( WELCOME_MESSAGE);
if (argc<2) { badusage(exename); return 1; }
for(i=1; i<argc; i++)
{
char* argument = argv[i];
if(!argument) continue; // Protection if argument empty
// Select command
if (argument[0]=='-')
{
argument ++;
// Display help on usage
if ( argument[0] =='h' ) { usage(exename); return 0; }
// Compression (default)
if ( argument[0] =='c' ) { if (argument[1] >='0') cLevel=argument[1] - '0'; continue; }
// Decoding
if ( argument[0] =='d' ) { decode=1; continue; }
// Bench
if ( argument[0] =='b' ) { bench=1; if (argument[1] >= '0') cLevel=argument[1] - '0'; continue; }
// Modify Block Size (benchmark only)
if ( argument[0] =='B' ) { int B = argument[1] - '0'; int S = 1 << (10 + 2*B); BMK_SetBlocksize(S); continue; }
// Modify Nb Iterations (benchmark only)
if ( argument[0] =='i' ) { int iters = argument[1] - '0'; BMK_SetNbIterations(iters); continue; }
// Pause at the end (benchmark only)
if ( argument[0] =='p' ) { BMK_SetPause(); continue; }
// Test
if ( argument[0] =='t' ) { decode=1; output_filename=nulmark; continue; }
}
// first provided filename is input
if (!input_filename) { input_filename=argument; filenamesStart=i; continue; }
// second provided filename is output
if (!output_filename)
{
output_filename=argument;
if (!strcmp (output_filename, nullinput)) output_filename = nulmark;
continue;
}
}
// No input filename ==> Error
if(!input_filename) { badusage(exename); return 1; }
if (bench) return BMK_benchFile(argv+filenamesStart, argc-filenamesStart, cLevel);
// No output filename ==> Error
if (!output_filename) { badusage(exename); return 1; }
if (decode) return decode_file(input_filename, output_filename);
return compress_file(input_filename, output_filename, cLevel); // Compression is 'default' action
}

View File

@ -1,6 +1,6 @@
/*
LZ4 HC - High Compression Mode of LZ4
Copyright (C) 2011-2012, Yann Collet.
Copyright (C) 2011-2013, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
@ -31,12 +31,24 @@
- LZ4 source repository : http://code.google.com/p/lz4/
*/
//**************************************
// Memory routines
//**************************************
#include <stdlib.h> // calloc, free
#define ALLOCATOR(s) calloc(1,s)
#define FREEMEM free
#include <string.h> // memset, memcpy
#define MEM_INIT memset
//**************************************
// CPU Feature Detection
//**************************************
// 32 or 64 bits ?
#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) || defined(__ppc64__) || defined(_WIN64) || defined(__LP64__) || defined(_LP64) ) // Detects 64 bits mode
#if (defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) \
|| defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) \
|| defined(__64BIT__) || defined(_LP64) || defined(__LP64__) \
|| defined(__ia64) || defined(__itanium__) || defined(_M_IA64) ) // Detects 64 bits mode
# define LZ4_ARCH64 1
#else
# define LZ4_ARCH64 0
@ -52,7 +64,7 @@
#elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN))
# define LZ4_BIG_ENDIAN 1
#elif defined(__sparc) || defined(__sparc__) \
|| defined(__ppc__) || defined(_POWER) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC) || defined(PPC) || defined(__powerpc__) || defined(__powerpc) || defined(powerpc) \
|| defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \
|| defined(__hpux) || defined(__hppa) \
|| defined(_MIPSEB) || defined(__s390__)
# define LZ4_BIG_ENDIAN 1
@ -76,78 +88,84 @@
//**************************************
// Compiler Options
//**************************************
#if __STDC_VERSION__ >= 199901L // C99
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99
/* "restrict" is a known keyword */
#else
# define restrict // Disable restrict
#endif
#ifdef _MSC_VER
# define inline __inline // Visual is not C99, but supports some kind of inline
# define forceinline __forceinline
# include <intrin.h> // For Visual 2005
# if LZ4_ARCH64 // 64-bit
#ifdef _MSC_VER // Visual Studio
# define FORCE_INLINE static __forceinline
# include <intrin.h> // For Visual 2005
# if LZ4_ARCH64 // 64-bits
# pragma intrinsic(_BitScanForward64) // For Visual 2005
# pragma intrinsic(_BitScanReverse64) // For Visual 2005
# else
# else // 32-bits
# pragma intrinsic(_BitScanForward) // For Visual 2005
# pragma intrinsic(_BitScanReverse) // For Visual 2005
# endif
# pragma warning(disable : 4127) // disable: C4127: conditional expression is constant
# pragma warning(disable : 4701) // disable: C4701: potentially uninitialized local variable used
#else
# ifdef __GNUC__
# define forceinline inline __attribute__((always_inline))
# define FORCE_INLINE static inline __attribute__((always_inline))
# else
# define forceinline inline
# define FORCE_INLINE static inline
# endif
#endif
#ifdef _MSC_VER // Visual Studio
#define lz4_bswap16(x) _byteswap_ushort(x)
# define lz4_bswap16(x) _byteswap_ushort(x)
#else
#define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)))
# define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)))
#endif
//**************************************
// Includes
//**************************************
#include <stdlib.h> // calloc, free
#include <string.h> // memset, memcpy
#include "lz4hc.h"
#define ALLOCATOR(s) calloc(1,s)
#define FREEMEM free
#define MEM_INIT memset
#include "lz4.h"
//**************************************
// Basic Types
//**************************************
#if defined(_MSC_VER) // Visual Studio does not support 'stdint' natively
#define BYTE unsigned __int8
#define U16 unsigned __int16
#define U32 unsigned __int32
#define S32 __int32
#define U64 unsigned __int64
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99
# include <stdint.h>
typedef uint8_t BYTE;
typedef uint16_t U16;
typedef uint32_t U32;
typedef int32_t S32;
typedef uint64_t U64;
#else
#include <stdint.h>
#define BYTE uint8_t
#define U16 uint16_t
#define U32 uint32_t
#define S32 int32_t
#define U64 uint64_t
typedef unsigned char BYTE;
typedef unsigned short U16;
typedef unsigned int U32;
typedef signed int S32;
typedef unsigned long long U64;
#endif
#ifndef LZ4_FORCE_UNALIGNED_ACCESS
#pragma pack(push, 1)
#if defined(__GNUC__) && !defined(LZ4_FORCE_UNALIGNED_ACCESS)
# define _PACKED __attribute__ ((packed))
#else
# define _PACKED
#endif
typedef struct _U16_S { U16 v; } U16_S;
typedef struct _U32_S { U32 v; } U32_S;
typedef struct _U64_S { U64 v; } U64_S;
#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__)
# ifdef __IBMC__
# pragma pack(1)
# else
# pragma pack(push, 1)
# endif
#endif
#ifndef LZ4_FORCE_UNALIGNED_ACCESS
#pragma pack(pop)
typedef struct _U16_S { U16 v; } _PACKED U16_S;
typedef struct _U32_S { U32 v; } _PACKED U32_S;
typedef struct _U64_S { U64 v; } _PACKED U64_S;
#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__)
# pragma pack(pop)
#endif
#define A64(x) (((U64_S *)(x))->v)
@ -182,34 +200,40 @@ typedef struct _U64_S { U64 v; } U64_S;
#define MINLENGTH (MFLIMIT+1)
#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
#define KB *(1U<<10)
#define MB *(1U<<20)
#define GB *(1U<<30)
//**************************************
// Architecture-specific macros
//**************************************
#if LZ4_ARCH64 // 64-bit
#define STEPSIZE 8
#define LZ4_COPYSTEP(s,d) A64(d) = A64(s); d+=8; s+=8;
#define LZ4_COPYPACKET(s,d) LZ4_COPYSTEP(s,d)
#define UARCH U64
#define AARCH A64
#define HTYPE U32
#define INITBASE(b,s) const BYTE* const b = s
#else // 32-bit
#define STEPSIZE 4
#define LZ4_COPYSTEP(s,d) A32(d) = A32(s); d+=4; s+=4;
#define LZ4_COPYPACKET(s,d) LZ4_COPYSTEP(s,d); LZ4_COPYSTEP(s,d);
#define UARCH U32
#define AARCH A32
#define HTYPE const BYTE*
#define INITBASE(b,s) const int b = 0
#if LZ4_ARCH64 // 64-bit
# define STEPSIZE 8
# define LZ4_COPYSTEP(s,d) A64(d) = A64(s); d+=8; s+=8;
# define LZ4_COPYPACKET(s,d) LZ4_COPYSTEP(s,d)
# define UARCH U64
# define AARCH A64
# define HTYPE U32
# define INITBASE(b,s) const BYTE* const b = s
#else // 32-bit
# define STEPSIZE 4
# define LZ4_COPYSTEP(s,d) A32(d) = A32(s); d+=4; s+=4;
# define LZ4_COPYPACKET(s,d) LZ4_COPYSTEP(s,d); LZ4_COPYSTEP(s,d);
# define UARCH U32
# define AARCH A32
//# define HTYPE const BYTE*
//# define INITBASE(b,s) const int b = 0
# define HTYPE U32
# define INITBASE(b,s) const BYTE* const b = s
#endif
#if defined(LZ4_BIG_ENDIAN)
#define LZ4_READ_LITTLEENDIAN_16(d,s,p) { U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; }
#define LZ4_WRITE_LITTLEENDIAN_16(p,i) { U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p+=2; }
#else // Little Endian
#define LZ4_READ_LITTLEENDIAN_16(d,s,p) { d = (s) - A16(p); }
#define LZ4_WRITE_LITTLEENDIAN_16(p,v) { A16(p) = v; p+=2; }
# define LZ4_READ_LITTLEENDIAN_16(d,s,p) { U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; }
# define LZ4_WRITE_LITTLEENDIAN_16(p,i) { U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p+=2; }
#else // Little Endian
# define LZ4_READ_LITTLEENDIAN_16(d,s,p) { d = (s) - A16(p); }
# define LZ4_WRITE_LITTLEENDIAN_16(p,v) { A16(p) = v; p+=2; }
#endif
@ -218,7 +242,9 @@ typedef struct _U64_S { U64 v; } U64_S;
//************************************************************
typedef struct
{
const BYTE* inputBuffer;
const BYTE* base;
const BYTE* end;
HTYPE hashTable[HASHTABLESIZE];
U16 chainTable[MAXD];
const BYTE* nextToUpdate;
@ -230,11 +256,11 @@ typedef struct
//**************************************
#define LZ4_WILDCOPY(s,d,e) do { LZ4_COPYPACKET(s,d) } while (d<e);
#define LZ4_BLINDCOPY(s,d,l) { BYTE* e=d+l; LZ4_WILDCOPY(s,d,e); d=e; }
#define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG))
#define HASH_VALUE(p) HASH_FUNCTION(A32(p))
#define HASH_POINTER(p) (HashTable[HASH_VALUE(p)] + base)
#define DELTANEXT(p) chainTable[(size_t)(p) & MAXD_MASK]
#define GETNEXT(p) ((p) - (size_t)DELTANEXT(p))
#define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG))
#define HASH_VALUE(p) HASH_FUNCTION(A32(p))
#define HASH_POINTER(p) (HashTable[HASH_VALUE(p)] + base)
#define DELTANEXT(p) chainTable[(size_t)(p) & MAXD_MASK]
#define GETNEXT(p) ((p) - (size_t)DELTANEXT(p))
//**************************************
@ -242,99 +268,98 @@ typedef struct
//**************************************
#if LZ4_ARCH64
inline static int LZ4_NbCommonBytes (register U64 val)
FORCE_INLINE int LZ4_NbCommonBytes (register U64 val)
{
#if defined(LZ4_BIG_ENDIAN)
#if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
unsigned long r = 0;
_BitScanReverse64( &r, val );
return (int)(r>>3);
#elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
# elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
return (__builtin_clzll(val) >> 3);
#else
# else
int r;
if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
r += (!val);
return r;
#endif
# endif
#else
#if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
unsigned long r = 0;
_BitScanForward64( &r, val );
return (int)(r>>3);
#elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
# elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
return (__builtin_ctzll(val) >> 3);
#else
# else
static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
return DeBruijnBytePos[((U64)((val & -val) * 0x0218A392CDABBD3F)) >> 58];
#endif
# endif
#endif
}
#else
inline static int LZ4_NbCommonBytes (register U32 val)
FORCE_INLINE int LZ4_NbCommonBytes (register U32 val)
{
#if defined(LZ4_BIG_ENDIAN)
#if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
unsigned long r;
_BitScanReverse( &r, val );
return (int)(r>>3);
#elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
# elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
return (__builtin_clz(val) >> 3);
#else
# else
int r;
if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
r += (!val);
return r;
#endif
# endif
#else
#if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
unsigned long r;
_BitScanForward( &r, val );
return (int)(r>>3);
#elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
# elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
return (__builtin_ctz(val) >> 3);
#else
# else
static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
#endif
# endif
#endif
}
#endif
inline static int LZ4HC_Init (LZ4HC_Data_Structure* hc4, const BYTE* base)
FORCE_INLINE void LZ4_initHC (LZ4HC_Data_Structure* hc4, const BYTE* base)
{
MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable));
MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
hc4->nextToUpdate = base + LZ4_ARCH64;
hc4->nextToUpdate = base + 1;
hc4->base = base;
return 1;
hc4->inputBuffer = base;
hc4->end = base;
}
inline static void* LZ4HC_Create (const BYTE* base)
void* LZ4_createHC (const char* inputBuffer)
{
void* hc4 = ALLOCATOR(sizeof(LZ4HC_Data_Structure));
LZ4HC_Init ((LZ4HC_Data_Structure*)hc4, base);
LZ4_initHC ((LZ4HC_Data_Structure*)hc4, (const BYTE*)inputBuffer);
return hc4;
}
inline static int LZ4HC_Free (void** LZ4HC_Data)
int LZ4_freeHC (void* LZ4HC_Data)
{
FREEMEM(*LZ4HC_Data);
*LZ4HC_Data = NULL;
return (1);
FREEMEM(LZ4HC_Data);
return (0);
}
// Update chains up to ip (excluded)
forceinline static void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)
FORCE_INLINE void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)
{
U16* chainTable = hc4->chainTable;
HTYPE* HashTable = hc4->hashTable;
@ -342,17 +367,37 @@ forceinline static void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)
while(hc4->nextToUpdate < ip)
{
const BYTE* p = hc4->nextToUpdate;
const BYTE* const p = hc4->nextToUpdate;
size_t delta = (p) - HASH_POINTER(p);
if (delta>MAX_DISTANCE) delta = MAX_DISTANCE;
DELTANEXT(p) = (U16)delta;
HashTable[HASH_VALUE(p)] = (p) - base;
HashTable[HASH_VALUE(p)] = (HTYPE)((p) - base);
hc4->nextToUpdate++;
}
}
forceinline static size_t LZ4HC_CommonLength (const BYTE* p1, const BYTE* p2, const BYTE* const matchlimit)
char* LZ4_slideInputBufferHC(void* LZ4HC_Data)
{
LZ4HC_Data_Structure* hc4 = (LZ4HC_Data_Structure*)LZ4HC_Data;
U32 distance = (U32)(hc4->end - hc4->inputBuffer) - 64 KB;
distance = (distance >> 16) << 16; // Must be a multiple of 64 KB
LZ4HC_Insert(hc4, hc4->end - MINMATCH);
memcpy((void*)(hc4->end - 64 KB - distance), (const void*)(hc4->end - 64 KB), 64 KB);
hc4->nextToUpdate -= distance;
hc4->base -= distance;
if ((U32)(hc4->inputBuffer - hc4->base) > 1 GB + 64 KB) // Avoid overflow
{
int i;
hc4->base += 1 GB;
for (i=0; i<HASHTABLESIZE; i++) hc4->hashTable[i] -= 1 GB;
}
hc4->end -= distance;
return (char*)(hc4->end);
}
FORCE_INLINE size_t LZ4HC_CommonLength (const BYTE* p1, const BYTE* p2, const BYTE* const matchlimit)
{
const BYTE* p1t = p1;
@ -370,7 +415,7 @@ forceinline static size_t LZ4HC_CommonLength (const BYTE* p1, const BYTE* p2, co
}
forceinline static int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* const matchlimit, const BYTE** matchpos)
FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* const matchlimit, const BYTE** matchpos)
{
U16* const chainTable = hc4->chainTable;
HTYPE* const HashTable = hc4->hashTable;
@ -378,7 +423,7 @@ forceinline static int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4,
INITBASE(base,hc4->base);
int nbAttempts=MAX_NB_ATTEMPTS;
size_t repl=0, ml=0;
U16 delta;
U16 delta=0; // useless assignment, to remove an uninitialization warning
// HC4 match finder
LZ4HC_Insert(hc4, ip);
@ -387,7 +432,7 @@ forceinline static int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4,
#define REPEAT_OPTIMIZATION
#ifdef REPEAT_OPTIMIZATION
// Detect repetitive sequences of length <= 4
if (ref >= ip-4) // potential repetition
if ((U32)(ip-ref) <= 4) // potential repetition
{
if (A32(ref) == A32(ip)) // confirmed
{
@ -399,7 +444,7 @@ forceinline static int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4,
}
#endif
while ((ref >= ip-MAX_DISTANCE) && (nbAttempts))
while (((U32)(ip-ref) <= MAX_DISTANCE) && (nbAttempts))
{
nbAttempts--;
if (*(ref+ml) == *(ip+ml))
@ -427,7 +472,7 @@ forceinline static int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4,
do
{
DELTANEXT(ptr) = delta;
HashTable[HASH_VALUE(ptr)] = (ptr) - base; // Head of chain
HashTable[HASH_VALUE(ptr)] = (HTYPE)((ptr) - base); // Head of chain
ptr++;
} while(ptr < end);
hc4->nextToUpdate = end;
@ -438,7 +483,7 @@ forceinline static int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4,
}
forceinline static int LZ4HC_InsertAndGetWiderMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* startLimit, const BYTE* matchlimit, int longest, const BYTE** matchpos, const BYTE** startpos)
FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* startLimit, const BYTE* matchlimit, int longest, const BYTE** matchpos, const BYTE** startpos)
{
U16* const chainTable = hc4->chainTable;
HTYPE* const HashTable = hc4->hashTable;
@ -451,7 +496,7 @@ forceinline static int LZ4HC_InsertAndGetWiderMatch (LZ4HC_Data_Structure* hc4,
LZ4HC_Insert(hc4, ip);
ref = HASH_POINTER(ip);
while ((ref >= ip-MAX_DISTANCE) && (nbAttempts))
while (((U32)(ip-ref) <= MAX_DISTANCE) && (nbAttempts))
{
nbAttempts--;
if (*(startLimit + longest) == *(ref - delta + longest))
@ -481,7 +526,7 @@ _endCount:
const BYTE* ipt = ip + MINMATCH + LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit);
#endif
while ((startt>startLimit) && (reft > hc4->base) && (startt[-1] == reft[-1])) {startt--; reft--;}
while ((startt>startLimit) && (reft > hc4->inputBuffer) && (startt[-1] == reft[-1])) {startt--; reft--;}
if ((ipt-startt) > longest)
{
@ -497,16 +542,26 @@ _endCount:
}
forceinline static int LZ4_encodeSequence(const BYTE** ip, BYTE** op, const BYTE** anchor, int ml, const BYTE* ref)
typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive;
FORCE_INLINE int LZ4HC_encodeSequence (
const BYTE** ip,
BYTE** op,
const BYTE** anchor,
int matchLength,
const BYTE* ref,
limitedOutput_directive limitedOutputBuffer,
BYTE* oend)
{
int length, len;
int length;
BYTE* token;
// Encode Literal length
length = (int)(*ip - *anchor);
token = (*op)++;
if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *(*op)++ = 255; *(*op)++ = (BYTE)len; }
else *token = (length<<ML_BITS);
if ((limitedOutputBuffer) && ((*op + length + (2 + 1 + LASTLITERALS) + (length>>8)) > oend)) return 1; // Check output limit
if (length>=(int)RUN_MASK) { int len; *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *(*op)++ = 255; *(*op)++ = (BYTE)len; }
else *token = (BYTE)(length<<ML_BITS);
// Copy Literals
LZ4_BLINDCOPY(*anchor, *op, length);
@ -515,36 +570,39 @@ forceinline static int LZ4_encodeSequence(const BYTE** ip, BYTE** op, const BYTE
LZ4_WRITE_LITTLEENDIAN_16(*op,(U16)(*ip-ref));
// Encode MatchLength
len = (int)(ml-MINMATCH);
if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (len > 254) { len-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)len; }
else *token += len;
length = (int)(matchLength-MINMATCH);
if ((limitedOutputBuffer) && (*op + (1 + LASTLITERALS) + (length>>8) > oend)) return 1; // Check output limit
if (length>=(int)ML_MASK) { *token+=ML_MASK; length-=ML_MASK; for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (length > 254) { length-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)length; }
else *token += (BYTE)(length);
// Prepare next loop
*ip += ml;
*ip += matchLength;
*anchor = *ip;
return 0;
}
//****************************
// Compression CODE
//****************************
int LZ4_compressHCCtx(LZ4HC_Data_Structure* ctx,
static int LZ4HC_compress_generic (
void* ctxvoid,
const char* source,
char* dest,
int isize)
{
int inputSize,
int maxOutputSize,
limitedOutput_directive limit
)
{
LZ4HC_Data_Structure* ctx = (LZ4HC_Data_Structure*) ctxvoid;
const BYTE* ip = (const BYTE*) source;
const BYTE* anchor = ip;
const BYTE* const iend = ip + isize;
const BYTE* const iend = ip + inputSize;
const BYTE* const mflimit = iend - MFLIMIT;
const BYTE* const matchlimit = (iend - LASTLITERALS);
BYTE* op = (BYTE*) dest;
BYTE* const oend = op + maxOutputSize;
int ml, ml2, ml3, ml0;
int ml, ml2, ml3, ml0;
const BYTE* ref=NULL;
const BYTE* start2=NULL;
const BYTE* ref2=NULL;
@ -553,6 +611,11 @@ int LZ4_compressHCCtx(LZ4HC_Data_Structure* ctx,
const BYTE* start0;
const BYTE* ref0;
// Ensure blocks follow each other
if (ip != ctx->end) return 0;
ctx->end += inputSize;
ip++;
// Main Loop
@ -573,7 +636,7 @@ _Search2:
if (ml2 == ml) // No better match
{
LZ4_encodeSequence(&ip, &op, &anchor, ml, ref);
if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
continue;
}
@ -625,9 +688,9 @@ _Search3:
// ip & ref are known; Now for ml
if (start2 < ip+ml) ml = (int)(start2 - ip);
// Now, encode 2 sequences
LZ4_encodeSequence(&ip, &op, &anchor, ml, ref);
if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
ip = start2;
LZ4_encodeSequence(&ip, &op, &anchor, ml2, ref2);
if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0;
continue;
}
@ -649,7 +712,7 @@ _Search3:
}
}
LZ4_encodeSequence(&ip, &op, &anchor, ml, ref);
if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
ip = start3;
ref = ref3;
ml = ml3;
@ -688,7 +751,7 @@ _Search3:
ml = (int)(start2 - ip);
}
}
LZ4_encodeSequence(&ip, &op, &anchor, ml, ref);
if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
ip = start2;
ref = ref2;
@ -705,8 +768,9 @@ _Search3:
// Encode Last Literals
{
int lastRun = (int)(iend - anchor);
if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; // Check output limit
if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
else *op++ = (lastRun<<ML_BITS);
else *op++ = (BYTE)(lastRun<<ML_BITS);
memcpy(op, anchor, iend - anchor);
op += iend-anchor;
}
@ -716,15 +780,38 @@ _Search3:
}
int LZ4_compressHC(const char* source,
char* dest,
int isize)
int LZ4_compressHC(const char* source, char* dest, int inputSize)
{
void* ctx = LZ4HC_Create((const BYTE*)source);
int result = LZ4_compressHCCtx(ctx, source, dest, isize);
LZ4HC_Free (&ctx);
void* ctx = LZ4_createHC(source);
int result;
if (ctx==NULL) return 0;
result = LZ4HC_compress_generic (ctx, source, dest, inputSize, 0, noLimit);
LZ4_freeHC(ctx);
return result;
}
int LZ4_compressHC_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize)
{
return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, noLimit);
}
int LZ4_compressHC_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize)
{
void* ctx = LZ4_createHC(source);
int result;
if (ctx==NULL) return 0;
result = LZ4HC_compress_generic (ctx, source, dest, inputSize, maxOutputSize, limitedOutput);
LZ4_freeHC(ctx);
return result;
}
int LZ4_compressHC_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize)
{
return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, limitedOutput);
}

View File

@ -1,7 +1,7 @@
/*
LZ4 HC - High Compression Mode of LZ4
Header File
Copyright (C) 2011-2012, Yann Collet.
Copyright (C) 2011-2013, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
@ -39,19 +39,70 @@ extern "C" {
#endif
int LZ4_compressHC (const char* source, char* dest, int isize);
int LZ4_compressHC (const char* source, char* dest, int inputSize);
/*
LZ4_compressHC :
return : the number of bytes in compressed buffer dest
note : destination buffer must be already allocated.
To avoid any problem, size it to handle worst cases situations (input data not compressible)
Worst case size evaluation is provided by function LZ4_compressBound() (see "lz4.h")
return : the number of bytes in compressed buffer dest
or 0 if compression fails.
note : destination buffer must be already allocated.
To avoid any problem, size it to handle worst cases situations (input data not compressible)
Worst case size evaluation is provided by function LZ4_compressBound() (see "lz4.h")
*/
int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize);
/*
LZ4_compress_limitedOutput() :
Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'.
If it cannot achieve it, compression will stop, and result of the function will be zero.
This function never writes outside of provided output buffer.
inputSize : Max supported value is 1 GB
maxOutputSize : is maximum allowed size into the destination buffer (which must be already allocated)
return : the number of output bytes written in buffer 'dest'
or 0 if compression fails.
*/
/* Note :
Decompression functions are provided within regular LZ4 source code (see "lz4.h") (BSD license)
Decompression functions are provided within LZ4 source code (see "lz4.h") (BSD license)
*/
/* Advanced Functions */
void* LZ4_createHC (const char* inputBuffer);
int LZ4_compressHC_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize);
int LZ4_compressHC_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize);
char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
int LZ4_freeHC (void* LZ4HC_Data);
/*
These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks.
In order to achieve this, it is necessary to start creating the LZ4HC Data Structure, thanks to the function :
void* LZ4_createHC (const char* inputBuffer);
The result of the function is the (void*) pointer on the LZ4HC Data Structure.
This pointer will be needed in all other functions.
If the pointer returned is NULL, then the allocation has failed, and compression must be aborted.
The only parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer.
The input buffer must be already allocated, and size at least 192KB.
'inputBuffer' will also be the 'const char* source' of the first block.
All blocks are expected to lay next to each other within the input buffer, starting from 'inputBuffer'.
To compress each block, use either LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue().
Their behavior are identical to LZ4_compressHC() or LZ4_compressHC_limitedOutput(),
but require the LZ4HC Data Structure as their first argument, and check that each block starts right after the previous one.
If next block does not begin immediately after the previous one, the compression will fail (return 0).
When it's no longer possible to lay the next block after the previous one (not enough space left into input buffer), a call to :
char* LZ4_slideInputBufferHC(void* LZ4HC_Data);
must be performed. It will typically copy the latest 64KB of input at the beginning of input buffer.
Note that, for this function to work properly, minimum size of an input buffer must be 192KB.
==> The memory position where the next input data block must start is provided as the result of the function.
Compression can then resume, using LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue(), as usual.
When compression is completed, a call to LZ4_freeHC() will release the memory used by the LZ4HC Data Structure.
*/

View File

@ -0,0 +1,12 @@
TUNTAP_VERSION = 20131028
BASE=
all: tap.kext
clean:
cd src/tap && make -f Makefile clean
tap.kext:
cd src/tap && make TUNTAP_VERSION=$(TUNTAP_VERSION) -f Makefile all
.PHONY: test

View File

@ -0,0 +1,23 @@
Building the tap for both x86_64 and i386 requires an older version of the
Xcode tools than what now ships for Mavericks (10.9). The newer version
does not support creating i386 kernel images.
At the moment this is done on an OSX 10.6 virtual image that is used for
building. (It doesn't have to be done often.) Then the kext is signed on
the regular build system. That's because images built on newer OSX don't
seem to load on 10.6 but 10.6 built kexts seem fine on 10.9. Go figure.
Older Xcode can also be found at:
https://developer.apple.com/downloads
It requires a bit of a dance to unpack the package and obtain an unpacked
tree, but once it's there you can change the line in tap/Makefile and
build for both architectures.
This will go on until i386 is thoroughly legacy, at which point we'll
probably start just supporting x86_64. But that might be a while. We want
to support old Macs through their entire useful life.
Since this build is irritating, a pre-built copy is packaged in ext/ and
is installed by 'make install'. So users shouldn't have to build this.

View File

@ -19,7 +19,7 @@ BUNDLE_SIGNATURE = ????
BUNDLE_PACKAGETYPE = KEXT
BUNDLE_VERSION = $(TAP_KEXT_VERSION)
INCLUDE = -I.. -I/System/Library/Frameworks/Kernel.framework/Headers
INCLUDE = -I.. -I/System/Library/Frameworks/Kernel.framework/Headers -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/Kernel.framework/Headers
CFLAGS = -Wall -mkernel -force_cpusubtype_ALL \
-fno-builtin -fno-stack-protector -arch i386 -arch x86_64 \
-DKERNEL -D__APPLE__ -DKERNEL_PRIVATE -DTUNTAP_VERSION=\"$(TUNTAP_VERSION)\" \
@ -27,8 +27,10 @@ CFLAGS = -Wall -mkernel -force_cpusubtype_ALL \
CCFLAGS = $(CFLAGS)
LDFLAGS = -Wall -mkernel -nostdlib -r -lcc_kext -arch i386 -arch x86_64 -Xlinker -kext
CCP = $(shell if [ -f /usr/bin/llvm-g++ ]; then echo llvm-g++; else echo g++; fi)
CC = gcc
#CCP = g++
#CC = gcc
CCP = ../../../../llvm-g++-Xcode4.6.2/bin/llvm-g++
CC = ../../../../llvm-g++-Xcode4.6.2/bin/llvm-gcc
all: $(KMOD_BIN) bundle

View File

@ -32,9 +32,8 @@
#define TAP_FAMILY_NAME ((char *) "zt")
#define TAP_IF_COUNT 16 /* max number of tap interfaces */
#define TAP_IF_COUNT 32 /* max number of tap interfaces */
// ZeroTier default MTU, see Constants.hpp
#define TAP_MTU 2800
#define TAP_LLADDR tap_lladdr

View File

@ -648,7 +648,9 @@ tuntap_interface::cdev_write(uio_t uio, int ioflag)
mb = first;
while (uio_resid(uio) > 0) {
/* copy a chunk. enforce mtu (don't know if this is correct behaviour) */
chunk_len = min(ifnet_mtu(ifp), min(uio_resid(uio), mlen));
// ... evidently not :) -- Adam Ierymenko <adam.ierymenko@zerotier.com>
//chunk_len = min(ifnet_mtu(ifp), min(uio_resid(uio), mlen));
chunk_len = min(uio_resid(uio),mlen);
error = uiomove((caddr_t) mbuf_data(mb), chunk_len, uio);
if (error) {
log(LOG_ERR, "tuntap: could not copy data from userspace: %d\n", error);
@ -664,7 +666,9 @@ tuntap_interface::cdev_write(uio_t uio, int ioflag)
copied += chunk_len;
/* if done, break the loop */
if (uio_resid(uio) <= 0 || copied >= ifnet_mtu(ifp))
//if (uio_resid(uio) <= 0 || copied >= ifnet_mtu(ifp))
// break;
if (uio_resid(uio) <= 0)
break;
/* allocate a new mbuf if the current is filled */

View File

@ -1,175 +0,0 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2012-2013 ZeroTier Networks LLC
*
* 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 <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include "node/Identity.hpp"
#include "node/Utils.hpp"
#include "node/C25519.hpp"
using namespace ZeroTier;
static void printHelp(char *pn)
{
std::cout << "Usage: " << pn << " <command> [<args>]" << std::endl << std::endl;
std::cout << "Commands:" << std::endl;
std::cout << "\tgenerate [<identity.secret>] [<identity.public>]" << std::endl;
std::cout << "\tvalidate <identity.secret/public>" << std::endl;
std::cout << "\tgetpublic <identity.secret>" << std::endl;
std::cout << "\tsign <identity.secret> <file>" << std::endl;
std::cout << "\tverify <identity.secret/public> <file> <signature>" << std::endl;
}
static Identity getIdFromArg(char *arg)
{
Identity id;
if ((strlen(arg) > 32)&&(arg[10] == ':')) { // identity is a literal on the command line
if (id.fromString(arg))
return id;
} else { // identity is to be read from a file
std::string idser;
if (Utils::readFile(arg,idser)) {
if (id.fromString(idser))
return id;
}
}
return Identity();
}
int main(int argc,char **argv)
{
if (argc < 2) {
printHelp(argv[0]);
return -1;
}
if (!strcmp(argv[1],"generate")) {
Identity id;
id.generate();
std::string idser = id.toString(true);
if (argc >= 3) {
if (!Utils::writeFile(argv[2],idser)) {
std::cerr << "Error writing to " << argv[2] << std::endl;
return -1;
} else std::cout << argv[2] << " written" << std::endl;
if (argc >= 4) {
idser = id.toString(false);
if (!Utils::writeFile(argv[3],idser)) {
std::cerr << "Error writing to " << argv[3] << std::endl;
return -1;
} else std::cout << argv[3] << " written" << std::endl;
}
} else std::cout << idser;
} else if (!strcmp(argv[1],"validate")) {
if (argc < 3) {
printHelp(argv[0]);
return -1;
}
Identity id = getIdFromArg(argv[2]);
if (!id) {
std::cerr << "Identity argument invalid or file unreadable: " << argv[2] << std::endl;
return -1;
}
if (!id.locallyValidate()) {
std::cerr << argv[2] << " FAILED validation." << std::endl;
return -1;
} else std::cout << argv[2] << " is a valid identity (full check performed)" << std::endl;
} else if (!strcmp(argv[1],"getpublic")) {
if (argc < 3) {
printHelp(argv[0]);
return -1;
}
Identity id = getIdFromArg(argv[2]);
if (!id) {
std::cerr << "Identity argument invalid or file unreadable: " << argv[2] << std::endl;
return -1;
}
std::cout << id.toString(false);
} else if (!strcmp(argv[1],"sign")) {
if (argc < 4) {
printHelp(argv[0]);
return -1;
}
Identity id = getIdFromArg(argv[2]);
if (!id) {
std::cerr << "Identity argument invalid or file unreadable: " << argv[2] << std::endl;
return -1;
}
if (!id.hasPrivate()) {
std::cerr << argv[2] << " does not contain a private key (must use private to sign)" << std::endl;
return -1;
}
std::string inf;
if (!Utils::readFile(argv[3],inf)) {
std::cerr << argv[3] << " is not readable" << std::endl;
return -1;
}
C25519::Signature signature = id.sign(inf.data(),inf.length());
std::cout << Utils::hex(signature.data,signature.size());
} else if (!strcmp(argv[1],"verify")) {
if (argc < 4) {
printHelp(argv[0]);
return -1;
}
Identity id = getIdFromArg(argv[2]);
if (!id) {
std::cerr << "Identity argument invalid or file unreadable: " << argv[2] << std::endl;
return -1;
}
std::string inf;
if (!Utils::readFile(argv[3],inf)) {
std::cerr << argv[3] << " is not readable" << std::endl;
return -1;
}
std::string signature(Utils::unhex(argv[4]));
if ((signature.length() > ZT_ADDRESS_LENGTH)&&(id.verify(inf.data(),inf.length(),signature.data(),signature.length()))) {
std::cout << argv[3] << " signature valid" << std::endl;
} else {
std::cerr << argv[3] << " signature check FAILED" << std::endl;
return -1;
}
} else {
printHelp(argv[0]);
return -1;
}
return 0;
}

View File

@ -1,141 +0,0 @@
November 1, 2011:
o Make the netmask address family fix work without knowledge of the struct
ifaddr definition. This fixes a crash on Lion, where the layout of the
structure has been changed, but at the cost of the fix no longer working for
IPv6. I think this is OK though, since mDNSResponder has been fixed on
Leopard and beyond to no longer require the hack.
o Proper multicast address checking for tun; multicast should now work reliably
with IP and IPv6 on tun also.
o A quite comprehensive test suite has been added that allows for quick release
testing.
o PPC support has been dropped due to XCode 4 no longer supporting PPC arch.
September 13, 2009:
o Change linker options to produce 64 bit kext bundle for Snow Leopard.
o Switch from kmem_alloc and friends to OSAlloc for memory allocation and
avoid the delay() call. Respective symbols are not available on 64 bit
kernels anymore.
September 5, 2009:
o Initial Snow Leopard port. Thanks to various people contributing patches in
the bugtracker. The new official version can only be compiled on Snow
Leopard but has been tested to work on all Tiger, Leopard and Snow Leopard
o Clean up unused locking code and switch to rwlocks even for simple mutexes,
which avoids a symbol incompatibility for Tiger and Leopard.
o Clean up compilation flags in the Makefiles.
July 4, 2008:
o Adapt the former Leopard package to also be installable on Tiger systems.
This obsoletes the Tiger version, both Leopard and Tiger are now supported
by a single package.
June 7, 2008:
o Protect the selwakeup() call by the lock. This fixes incorrect select()
behaviour, thanks to Roland Wendelin for reporting this.
o Fix tuntap_mbuf_queue::size initialization
o Use a proper wait condition for synchronization when detaching the network
interface. The old code would crash if the if_detached() handler was called
from a different thread than unregister_interface().
January 21, 2008:
o Work around an issue in the Darwin kernel. When unregistering an interface,
addresses are not properly removed from the interface. This leads to
crashes and other problems when reusing the interface. Introduce an ugly
hack that tries to remove all interface addresses when shutting the
interface down.
o Fix a small mbuf leak that could occur when the output queue was full.
Thanks to Oleg Dolgov for reporting this.
December 21, 2007:
o Fix paths in the startup item postflight scripts
o Check if_ioctl arguments more defensively after a report of a panic after
receiving a NULL arg.
November 14, 2007:
o I have done a complete rework of the installer package generation. The
package is now edited in PackageMaker. The distribution package can still
be built from the commandline though.
o Fix incorrect permission & ownership of the installed files.
Oktober 11, 2007:
o Fix the permissions of the postflight scripts. Installer packages should work
again.
o Drop the kmod and kmodc++ in the linker command, they seem to be unneeded
with Leopard.
September 20, 2007:
o Initial Leopard port, it's basically the latest Tiger version with some
Leopard-related fixes and s/Tiger/Leopard/g
o I have switched to a proper version management system (git) and could
remove some of the CVS hacks subsequently.
o The installation packages have been reworked a bit, they now install into
/System/Extensions and /System/StartupItems directly by using
DestinationPaths.
May 13, 2006:
o This version is not stable, it may crash, sorry.
o Universal binaries that run on ppc and intel macs.
o Adds tap MAC address randomization
o Redesigned locking.
o Better multicast support
o mDNSResponder workaround, so that the tap interfaces should get picked up
now. Note that we are fixing ifconfig/kernel behaviour here.
o All tapX and tunX devices are visible in /dev at all times, network
interfaces still created dynamically, though.
o Startup items moved to /Library/StartupItems
May 17, 2005:
o Initial Tiger port. We now have KPI-style interfaces. I guess the Tiger
version is little slower than the Panther version because of all the
wrapping and hiding in the kernel.
o The kernel extensions moved to /Library/Extensions. That is the place where
non-Apple kexts are supposed to live.
April 21, 2005:
o I added support in tun for AF prepending like some BSDs do. Thanks to Dennis
kSchneider for mailing the initial patch. You can also set the value of
AF_INET6 to be used.
o I finally found that major bug causing crashes (especially on multiprocessor
machines). It also caused a memory leak (lost mbufs), and might have caused
performance/througput/data-loss problems. Everyone is recommended to upgrade.
April 6, 2005:
o I rewrote the common part concerning the tun and tap initialization and
cleanup. This should make the code more maintainable (less duplication).
o The devices now reinitialize to the state they were started in when they
are closed by an application. This concerns IP addresses for example.
o I changed the package building system to use PackageMaker.app in batch
mode. The packages also check for version 10.3 now, so nobody should be
able to install tun/tap on 10.2 using installer packages. Furthermore I
have sprinkled some warnings telling you not to use tun/tap on SMP machines
over the installation process ;-)
o Some minor locking fixes.
November 19, 2004:
o Jamie Wood reported that the packet queue in the driver could be considered
empty even if there were packets in it. This was probably caused by a
synchronization problem that should be fixed now. People encountering
timeouts etc. should try the new version.
o I finally implemented support for changing the interface MTU. The driver
enforces the MTU when writing packets to the character device now. However,
packets coming from the kernel are not checked.
September 9, 2004:
o Marcello Teodori told me that the tun driver wasn't working with openvpn.
The problem was the fcntl call, fixed that. Should work now. Thanks
Marcello!
o changed the tun driver not to prepend the address family field before each
and every packet (which is the behaviour of OpenBSD). As there is currently
only IPv4 and IPv6 support there is no problem with the standard tun
approach used on other OSes. This should make the driver much more
compatible.
o Did a script and makefile support so that the installer packages can now be
built from the command prompt. Unfortunately this might break things
someday as I am not using the 'official' way to build the packages
o Cleaned up installer packages a little.
August 24, 2004:
o initial version put online
o basic tun/tap support, tap working with qemu

Some files were not shown because too many files have changed in this diff Show More