mirror of
https://github.com/NAStools/zerotierone.git
synced 2025-08-21 05:44:10 -07:00
Imported Upstream version 1.1.14
This commit is contained in:
commit
bb232b9d52
557 changed files with 115164 additions and 0 deletions
10
ext/README.md
Normal file
10
ext/README.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
Miscellaneous Stuff
|
||||
======
|
||||
|
||||
This subfolder contains:
|
||||
|
||||
* Bundled third party libraries that are compiled into the binary on platforms and Linux distributions where they are not available on the system.
|
||||
|
||||
* Pre-compiled binaries for some platforms, such as pre-built and signed drivers for Mac and Windows.
|
||||
|
||||
* Miscellaneous files used by installers and packages on various platform targets.
|
36
ext/bin/tap-mac/tap.kext/Contents/Info.plist
Normal file
36
ext/bin/tap-mac/tap.kext/Contents/Info.plist
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>tap</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.zerotier.tap</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>tap</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>KEXT</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>20150118</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>OSBundleLibraries</key>
|
||||
<dict>
|
||||
<key>com.apple.kpi.mach</key>
|
||||
<string>8.0</string>
|
||||
<key>com.apple.kpi.bsd</key>
|
||||
<string>8.0</string>
|
||||
<key>com.apple.kpi.libkern</key>
|
||||
<string>8.0</string>
|
||||
<key>com.apple.kpi.unsupported</key>
|
||||
<string>8.0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
BIN
ext/bin/tap-mac/tap.kext/Contents/MacOS/tap
Executable file
BIN
ext/bin/tap-mac/tap.kext/Contents/MacOS/tap
Executable file
Binary file not shown.
105
ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeResources
Normal file
105
ext/bin/tap-mac/tap.kext/Contents/_CodeSignature/CodeResources
Normal 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>
|
BIN
ext/bin/tap-windows-ndis5/x64/WdfCoinstaller01011.dll
Normal file
BIN
ext/bin/tap-windows-ndis5/x64/WdfCoinstaller01011.dll
Normal file
Binary file not shown.
BIN
ext/bin/tap-windows-ndis5/x64/zttap200.cat
Normal file
BIN
ext/bin/tap-windows-ndis5/x64/zttap200.cat
Normal file
Binary file not shown.
79
ext/bin/tap-windows-ndis5/x64/zttap200.inf
Normal file
79
ext/bin/tap-windows-ndis5/x64/zttap200.inf
Normal file
|
@ -0,0 +1,79 @@
|
|||
[Version]
|
||||
Signature="$WINDOWS NT$"
|
||||
Class=Net
|
||||
ClassGuid={4d36e972-e325-11ce-bfc1-08002be10318}
|
||||
Provider=%Provider%
|
||||
CatalogFile=zttap200.cat
|
||||
DriverVer=01/23/2014,15.19.17.816
|
||||
|
||||
[Strings]
|
||||
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%=zttap200,NTamd64
|
||||
|
||||
[zttap200]
|
||||
%DeviceDescription%=zttap200.ndi,zttap200
|
||||
|
||||
[ztTap200.NTamd64]
|
||||
%DeviceDescription%=zttap200.ndi,zttap200
|
||||
|
||||
[zttap200.ndi]
|
||||
CopyFiles = zttap200.driver,zttap200.files
|
||||
AddReg = zttap200.reg
|
||||
AddReg = zttap200.params.reg
|
||||
Characteristics = 0x81
|
||||
|
||||
[zttap200.ndi.Services]
|
||||
AddService = zttap200, 2, zttap200.service
|
||||
|
||||
[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%"
|
||||
|
||||
[zttap200.params.reg]
|
||||
HKR, Ndi\params\MTU, ParamDesc, 0, "MTU"
|
||||
HKR, Ndi\params\MTU, Type, 0, "int"
|
||||
HKR, Ndi\params\MTU, Default, 0, "2800"
|
||||
HKR, Ndi\params\MTU, Optional, 0, "0"
|
||||
HKR, Ndi\params\MTU, Min, 0, "100"
|
||||
HKR, Ndi\params\MTU, Max, 0, "2800"
|
||||
HKR, Ndi\params\MTU, Step, 0, "1"
|
||||
HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status"
|
||||
HKR, Ndi\params\MediaStatus, Type, 0, "enum"
|
||||
HKR, Ndi\params\MediaStatus, Default, 0, "0"
|
||||
HKR, Ndi\params\MediaStatus, Optional, 0, "0"
|
||||
HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled"
|
||||
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"
|
||||
|
||||
[zttap200.service]
|
||||
DisplayName = %DeviceDescription%
|
||||
ServiceType = 1
|
||||
StartType = 3
|
||||
ErrorControl = 1
|
||||
LoadOrderGroup = NDIS
|
||||
ServiceBinary = %12%\zttap200.sys
|
||||
|
||||
[SourceDisksNames]
|
||||
1 = %DeviceDescription%, zttap200.sys
|
||||
|
||||
[SourceDisksFiles]
|
||||
zttap200.sys = 1
|
||||
|
||||
[DestinationDirs]
|
||||
zttap200.files = 11
|
||||
zttap200.driver = 12
|
||||
|
||||
[zttap200.files]
|
||||
;
|
||||
|
||||
[zttap200.driver]
|
||||
zttap200.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK
|
BIN
ext/bin/tap-windows-ndis5/x64/zttap200.sys
Normal file
BIN
ext/bin/tap-windows-ndis5/x64/zttap200.sys
Normal file
Binary file not shown.
BIN
ext/bin/tap-windows-ndis5/x86/WdfCoinstaller01011.dll
Normal file
BIN
ext/bin/tap-windows-ndis5/x86/WdfCoinstaller01011.dll
Normal file
Binary file not shown.
BIN
ext/bin/tap-windows-ndis5/x86/zttap200.cat
Normal file
BIN
ext/bin/tap-windows-ndis5/x86/zttap200.cat
Normal file
Binary file not shown.
76
ext/bin/tap-windows-ndis5/x86/zttap200.inf
Normal file
76
ext/bin/tap-windows-ndis5/x86/zttap200.inf
Normal file
|
@ -0,0 +1,76 @@
|
|||
[Version]
|
||||
Signature="$WINDOWS NT$"
|
||||
Class=Net
|
||||
ClassGuid={4d36e972-e325-11ce-bfc1-08002be10318}
|
||||
Provider=%Provider%
|
||||
CatalogFile=zttap200.cat
|
||||
DriverVer=01/24/2014,17.25.51.226
|
||||
|
||||
[Strings]
|
||||
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%=zttap200
|
||||
|
||||
[zttap200]
|
||||
%DeviceDescription%=zttap200.ndi,zttap200
|
||||
|
||||
[zttap200.ndi]
|
||||
CopyFiles = zttap200.driver,zttap200.files
|
||||
AddReg = zttap200.reg
|
||||
AddReg = zttap200.params.reg
|
||||
Characteristics = 0x81
|
||||
|
||||
[zttap200.ndi.Services]
|
||||
AddService = zttap200, 2, zttap200.service
|
||||
|
||||
[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%"
|
||||
|
||||
[zttap200.params.reg]
|
||||
HKR, Ndi\params\MTU, ParamDesc, 0, "MTU"
|
||||
HKR, Ndi\params\MTU, Type, 0, "int"
|
||||
HKR, Ndi\params\MTU, Default, 0, "2800"
|
||||
HKR, Ndi\params\MTU, Optional, 0, "0"
|
||||
HKR, Ndi\params\MTU, Min, 0, "100"
|
||||
HKR, Ndi\params\MTU, Max, 0, "2800"
|
||||
HKR, Ndi\params\MTU, Step, 0, "1"
|
||||
HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status"
|
||||
HKR, Ndi\params\MediaStatus, Type, 0, "enum"
|
||||
HKR, Ndi\params\MediaStatus, Default, 0, "0"
|
||||
HKR, Ndi\params\MediaStatus, Optional, 0, "0"
|
||||
HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled"
|
||||
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"
|
||||
|
||||
[zttap200.service]
|
||||
DisplayName = %DeviceDescription%
|
||||
ServiceType = 1
|
||||
StartType = 3
|
||||
ErrorControl = 1
|
||||
LoadOrderGroup = NDIS
|
||||
ServiceBinary = %12%\zttap200.sys
|
||||
|
||||
[SourceDisksNames]
|
||||
1 = %DeviceDescription%, zttap200.sys
|
||||
|
||||
[SourceDisksFiles]
|
||||
zttap200.sys = 1
|
||||
|
||||
[DestinationDirs]
|
||||
zttap200.files = 11
|
||||
zttap200.driver = 12
|
||||
|
||||
[zttap200.files]
|
||||
;
|
||||
|
||||
[zttap200.driver]
|
||||
zttap200.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK
|
BIN
ext/bin/tap-windows-ndis5/x86/zttap200.sys
Normal file
BIN
ext/bin/tap-windows-ndis5/x86/zttap200.sys
Normal file
Binary file not shown.
BIN
ext/bin/tap-windows-ndis6/x64/ZeroTierOne_NDIS6_x64.msi
Normal file
BIN
ext/bin/tap-windows-ndis6/x64/ZeroTierOne_NDIS6_x64.msi
Normal file
Binary file not shown.
BIN
ext/bin/tap-windows-ndis6/x64/zttap300.cat
Normal file
BIN
ext/bin/tap-windows-ndis6/x64/zttap300.cat
Normal file
Binary file not shown.
143
ext/bin/tap-windows-ndis6/x64/zttap300.inf
Normal file
143
ext/bin/tap-windows-ndis6/x64/zttap300.inf
Normal file
|
@ -0,0 +1,143 @@
|
|||
;
|
||||
; ZeroTier One Virtual Network Port NDIS6 Driver
|
||||
;
|
||||
; Based on the OpenVPN tap-windows6 driver version 9.21.1 git
|
||||
; commit 48f027cfca52b16b5fd23d82e6016ed8a91fc4d3.
|
||||
; See: https://github.com/OpenVPN/tap-windows6
|
||||
;
|
||||
; Modified by ZeroTier, Inc. - https://www.zerotier.com/
|
||||
;
|
||||
; (1) Comment out 'tun' functionality and related features such as DHCP
|
||||
; emulation, since we don't use any of that. Just want straight 'tap'.
|
||||
; (2) Added custom IOCTL to enumerate L2 multicast memberships.
|
||||
; (3) Increase maximum number of multicast memberships to 128.
|
||||
; (4) Set default and max device MTU to 2800.
|
||||
; (5) Rename/rebrand driver as ZeroTier network port driver.
|
||||
;
|
||||
; Original copyright below. Modifications released under GPLv2 as well.
|
||||
;
|
||||
; ****************************************************************************
|
||||
; * Copyright (C) 2002-2014 OpenVPN Technologies, Inc. *
|
||||
; * This program is free software; you can redistribute it and/or modify *
|
||||
; * it under the terms of the GNU General Public License version 2 *
|
||||
; * as published by the Free Software Foundation. *
|
||||
; ****************************************************************************
|
||||
;
|
||||
|
||||
[Version]
|
||||
Signature = "$Windows NT$"
|
||||
CatalogFile = zttap300.cat
|
||||
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
|
||||
Provider = %Provider%
|
||||
Class = Net
|
||||
DriverVer=08/13/2015,6.2.9200.20557
|
||||
|
||||
[Strings]
|
||||
DeviceDescription = "ZeroTier One Virtual Port"
|
||||
Provider = "ZeroTier Networks LLC" ; We're ZeroTier, Inc. now but kernel mode certs are $300+ so fuqdat.
|
||||
|
||||
; To build for x86, take NTamd64 off this and off the named section manually, build, then put it back!
|
||||
[Manufacturer]
|
||||
%Provider%=zttap300,NTamd64
|
||||
|
||||
[zttap300]
|
||||
%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated
|
||||
%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy
|
||||
|
||||
[zttap300.NTamd64]
|
||||
%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated
|
||||
%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy
|
||||
|
||||
;----------------- Characteristics ------------
|
||||
; NCF_PHYSICAL = 0x04
|
||||
; NCF_VIRTUAL = 0x01
|
||||
; NCF_SOFTWARE_ENUMERATED = 0x02
|
||||
; NCF_HIDDEN = 0x08
|
||||
; NCF_NO_SERVICE = 0x10
|
||||
; NCF_HAS_UI = 0x80
|
||||
;----------------- Characteristics ------------
|
||||
[zttap300.ndi]
|
||||
CopyFiles = zttap300.driver, zttap300.files
|
||||
AddReg = zttap300.reg
|
||||
AddReg = zttap300.params.reg
|
||||
Characteristics = 0x81
|
||||
*IfType = 0x6 ; IF_TYPE_ETHERNET_CSMACD
|
||||
*MediaType = 0x0 ; NdisMedium802_3
|
||||
*PhysicalMediaType = 14 ; NdisPhysicalMedium802_3
|
||||
|
||||
[zttap300.ndi.Services]
|
||||
AddService = zttap300, 2, zttap300.service
|
||||
|
||||
[zttap300.reg]
|
||||
HKR, Ndi, Service, 0, "zttap300"
|
||||
HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" ; yes, 'ndis5' is correct... yup, Windows.
|
||||
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
|
||||
HKR, , Manufacturer, 0, "%Provider%"
|
||||
HKR, , ProductName, 0, "%DeviceDescription%"
|
||||
|
||||
[zttap300.params.reg]
|
||||
HKR, Ndi\params\MTU, ParamDesc, 0, "MTU"
|
||||
HKR, Ndi\params\MTU, Type, 0, "int"
|
||||
HKR, Ndi\params\MTU, Default, 0, "2800"
|
||||
HKR, Ndi\params\MTU, Optional, 0, "0"
|
||||
HKR, Ndi\params\MTU, Min, 0, "100"
|
||||
HKR, Ndi\params\MTU, Max, 0, "2800"
|
||||
HKR, Ndi\params\MTU, Step, 0, "1"
|
||||
HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status"
|
||||
HKR, Ndi\params\MediaStatus, Type, 0, "enum"
|
||||
HKR, Ndi\params\MediaStatus, Default, 0, "0"
|
||||
HKR, Ndi\params\MediaStatus, Optional, 0, "0"
|
||||
HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled"
|
||||
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"
|
||||
|
||||
;---------- Service Type -------------
|
||||
; SERVICE_KERNEL_DRIVER = 0x01
|
||||
; SERVICE_WIN32_OWN_PROCESS = 0x10
|
||||
;---------- Service Type -------------
|
||||
|
||||
;---------- Start Mode ---------------
|
||||
; SERVICE_BOOT_START = 0x0
|
||||
; SERVICE_SYSTEM_START = 0x1
|
||||
; SERVICE_AUTO_START = 0x2
|
||||
; SERVICE_DEMAND_START = 0x3
|
||||
; SERVICE_DISABLED = 0x4
|
||||
;---------- Start Mode ---------------
|
||||
|
||||
[zttap300.service]
|
||||
DisplayName = %DeviceDescription%
|
||||
ServiceType = 1
|
||||
StartType = 3
|
||||
ErrorControl = 1
|
||||
LoadOrderGroup = NDIS
|
||||
ServiceBinary = %12%\zttap300.sys
|
||||
|
||||
;----------------- Copy Flags ------------
|
||||
; COPYFLG_NOSKIP = 0x02
|
||||
; COPYFLG_NOVERSIONCHECK = 0x04
|
||||
;----------------- Copy Flags ------------
|
||||
|
||||
[SourceDisksNames]
|
||||
1 = %DeviceDescription%, zttap300.sys
|
||||
|
||||
[SourceDisksFiles]
|
||||
zttap300.sys = 1
|
||||
|
||||
[DestinationDirs]
|
||||
zttap300.files = 11
|
||||
zttap300.driver = 12
|
||||
|
||||
[zttap300.files]
|
||||
;
|
||||
|
||||
[zttap300.driver]
|
||||
zttap300.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK
|
||||
|
BIN
ext/bin/tap-windows-ndis6/x64/zttap300.sys
Normal file
BIN
ext/bin/tap-windows-ndis6/x64/zttap300.sys
Normal file
Binary file not shown.
BIN
ext/bin/tap-windows-ndis6/x86/ZeroTierOne_NDIS6_x86.msi
Normal file
BIN
ext/bin/tap-windows-ndis6/x86/ZeroTierOne_NDIS6_x86.msi
Normal file
Binary file not shown.
BIN
ext/bin/tap-windows-ndis6/x86/zttap300.cat
Normal file
BIN
ext/bin/tap-windows-ndis6/x86/zttap300.cat
Normal file
Binary file not shown.
143
ext/bin/tap-windows-ndis6/x86/zttap300.inf
Normal file
143
ext/bin/tap-windows-ndis6/x86/zttap300.inf
Normal file
|
@ -0,0 +1,143 @@
|
|||
;
|
||||
; ZeroTier One Virtual Network Port NDIS6 Driver
|
||||
;
|
||||
; Based on the OpenVPN tap-windows6 driver version 9.21.1 git
|
||||
; commit 48f027cfca52b16b5fd23d82e6016ed8a91fc4d3.
|
||||
; See: https://github.com/OpenVPN/tap-windows6
|
||||
;
|
||||
; Modified by ZeroTier, Inc. - https://www.zerotier.com/
|
||||
;
|
||||
; (1) Comment out 'tun' functionality and related features such as DHCP
|
||||
; emulation, since we don't use any of that. Just want straight 'tap'.
|
||||
; (2) Added custom IOCTL to enumerate L2 multicast memberships.
|
||||
; (3) Increase maximum number of multicast memberships to 128.
|
||||
; (4) Set default and max device MTU to 2800.
|
||||
; (5) Rename/rebrand driver as ZeroTier network port driver.
|
||||
;
|
||||
; Original copyright below. Modifications released under GPLv2 as well.
|
||||
;
|
||||
; ****************************************************************************
|
||||
; * Copyright (C) 2002-2014 OpenVPN Technologies, Inc. *
|
||||
; * This program is free software; you can redistribute it and/or modify *
|
||||
; * it under the terms of the GNU General Public License version 2 *
|
||||
; * as published by the Free Software Foundation. *
|
||||
; ****************************************************************************
|
||||
;
|
||||
|
||||
[Version]
|
||||
Signature = "$Windows NT$"
|
||||
CatalogFile = zttap300.cat
|
||||
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
|
||||
Provider = %Provider%
|
||||
Class = Net
|
||||
DriverVer=08/13/2015,6.2.9200.20557
|
||||
|
||||
[Strings]
|
||||
DeviceDescription = "ZeroTier One Virtual Port"
|
||||
Provider = "ZeroTier Networks LLC" ; We're ZeroTier, Inc. now but kernel mode certs are $300+ so fuqdat.
|
||||
|
||||
; To build for x86, take NTamd64 off this and off the named section manually, build, then put it back!
|
||||
[Manufacturer]
|
||||
%Provider%=zttap300,NTamd64
|
||||
|
||||
[zttap300]
|
||||
%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated
|
||||
%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy
|
||||
|
||||
[zttap300.NTamd64]
|
||||
%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated
|
||||
%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy
|
||||
|
||||
;----------------- Characteristics ------------
|
||||
; NCF_PHYSICAL = 0x04
|
||||
; NCF_VIRTUAL = 0x01
|
||||
; NCF_SOFTWARE_ENUMERATED = 0x02
|
||||
; NCF_HIDDEN = 0x08
|
||||
; NCF_NO_SERVICE = 0x10
|
||||
; NCF_HAS_UI = 0x80
|
||||
;----------------- Characteristics ------------
|
||||
[zttap300.ndi]
|
||||
CopyFiles = zttap300.driver, zttap300.files
|
||||
AddReg = zttap300.reg
|
||||
AddReg = zttap300.params.reg
|
||||
Characteristics = 0x81
|
||||
*IfType = 0x6 ; IF_TYPE_ETHERNET_CSMACD
|
||||
*MediaType = 0x0 ; NdisMedium802_3
|
||||
*PhysicalMediaType = 14 ; NdisPhysicalMedium802_3
|
||||
|
||||
[zttap300.ndi.Services]
|
||||
AddService = zttap300, 2, zttap300.service
|
||||
|
||||
[zttap300.reg]
|
||||
HKR, Ndi, Service, 0, "zttap300"
|
||||
HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" ; yes, 'ndis5' is correct... yup, Windows.
|
||||
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
|
||||
HKR, , Manufacturer, 0, "%Provider%"
|
||||
HKR, , ProductName, 0, "%DeviceDescription%"
|
||||
|
||||
[zttap300.params.reg]
|
||||
HKR, Ndi\params\MTU, ParamDesc, 0, "MTU"
|
||||
HKR, Ndi\params\MTU, Type, 0, "int"
|
||||
HKR, Ndi\params\MTU, Default, 0, "2800"
|
||||
HKR, Ndi\params\MTU, Optional, 0, "0"
|
||||
HKR, Ndi\params\MTU, Min, 0, "100"
|
||||
HKR, Ndi\params\MTU, Max, 0, "2800"
|
||||
HKR, Ndi\params\MTU, Step, 0, "1"
|
||||
HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status"
|
||||
HKR, Ndi\params\MediaStatus, Type, 0, "enum"
|
||||
HKR, Ndi\params\MediaStatus, Default, 0, "0"
|
||||
HKR, Ndi\params\MediaStatus, Optional, 0, "0"
|
||||
HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled"
|
||||
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"
|
||||
|
||||
;---------- Service Type -------------
|
||||
; SERVICE_KERNEL_DRIVER = 0x01
|
||||
; SERVICE_WIN32_OWN_PROCESS = 0x10
|
||||
;---------- Service Type -------------
|
||||
|
||||
;---------- Start Mode ---------------
|
||||
; SERVICE_BOOT_START = 0x0
|
||||
; SERVICE_SYSTEM_START = 0x1
|
||||
; SERVICE_AUTO_START = 0x2
|
||||
; SERVICE_DEMAND_START = 0x3
|
||||
; SERVICE_DISABLED = 0x4
|
||||
;---------- Start Mode ---------------
|
||||
|
||||
[zttap300.service]
|
||||
DisplayName = %DeviceDescription%
|
||||
ServiceType = 1
|
||||
StartType = 3
|
||||
ErrorControl = 1
|
||||
LoadOrderGroup = NDIS
|
||||
ServiceBinary = %12%\zttap300.sys
|
||||
|
||||
;----------------- Copy Flags ------------
|
||||
; COPYFLG_NOSKIP = 0x02
|
||||
; COPYFLG_NOVERSIONCHECK = 0x04
|
||||
;----------------- Copy Flags ------------
|
||||
|
||||
[SourceDisksNames]
|
||||
1 = %DeviceDescription%, zttap300.sys
|
||||
|
||||
[SourceDisksFiles]
|
||||
zttap300.sys = 1
|
||||
|
||||
[DestinationDirs]
|
||||
zttap300.files = 11
|
||||
zttap300.driver = 12
|
||||
|
||||
[zttap300.files]
|
||||
;
|
||||
|
||||
[zttap300.driver]
|
||||
zttap300.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK
|
||||
|
BIN
ext/bin/tap-windows-ndis6/x86/zttap300.sys
Normal file
BIN
ext/bin/tap-windows-ndis6/x86/zttap300.sys
Normal file
Binary file not shown.
68
ext/http-parser/AUTHORS
Normal file
68
ext/http-parser/AUTHORS
Normal file
|
@ -0,0 +1,68 @@
|
|||
# Authors ordered by first contribution.
|
||||
Ryan Dahl <ry@tinyclouds.org>
|
||||
Jeremy Hinegardner <jeremy@hinegardner.org>
|
||||
Sergey Shepelev <temotor@gmail.com>
|
||||
Joe Damato <ice799@gmail.com>
|
||||
tomika <tomika_nospam@freemail.hu>
|
||||
Phoenix Sol <phoenix@burninglabs.com>
|
||||
Cliff Frey <cliff@meraki.com>
|
||||
Ewen Cheslack-Postava <ewencp@cs.stanford.edu>
|
||||
Santiago Gala <sgala@apache.org>
|
||||
Tim Becker <tim.becker@syngenio.de>
|
||||
Jeff Terrace <jterrace@gmail.com>
|
||||
Ben Noordhuis <info@bnoordhuis.nl>
|
||||
Nathan Rajlich <nathan@tootallnate.net>
|
||||
Mark Nottingham <mnot@mnot.net>
|
||||
Aman Gupta <aman@tmm1.net>
|
||||
Tim Becker <tim.becker@kuriositaet.de>
|
||||
Sean Cunningham <sean.cunningham@mandiant.com>
|
||||
Peter Griess <pg@std.in>
|
||||
Salman Haq <salman.haq@asti-usa.com>
|
||||
Cliff Frey <clifffrey@gmail.com>
|
||||
Jon Kolb <jon@b0g.us>
|
||||
Fouad Mardini <f.mardini@gmail.com>
|
||||
Paul Querna <pquerna@apache.org>
|
||||
Felix Geisendörfer <felix@debuggable.com>
|
||||
koichik <koichik@improvement.jp>
|
||||
Andre Caron <andre.l.caron@gmail.com>
|
||||
Ivo Raisr <ivosh@ivosh.net>
|
||||
James McLaughlin <jamie@lacewing-project.org>
|
||||
David Gwynne <loki@animata.net>
|
||||
Thomas LE ROUX <thomas@november-eleven.fr>
|
||||
Randy Rizun <rrizun@ortivawireless.com>
|
||||
Andre Louis Caron <andre.louis.caron@usherbrooke.ca>
|
||||
Simon Zimmermann <simonz05@gmail.com>
|
||||
Erik Dubbelboer <erik@dubbelboer.com>
|
||||
Martell Malone <martellmalone@gmail.com>
|
||||
Bertrand Paquet <bpaquet@octo.com>
|
||||
BogDan Vatra <bogdan@kde.org>
|
||||
Peter Faiman <peter@thepicard.org>
|
||||
Corey Richardson <corey@octayn.net>
|
||||
Tóth Tamás <tomika_nospam@freemail.hu>
|
||||
Cam Swords <cam.swords@gmail.com>
|
||||
Chris Dickinson <christopher.s.dickinson@gmail.com>
|
||||
Uli Köhler <ukoehler@btronik.de>
|
||||
Charlie Somerville <charlie@charliesomerville.com>
|
||||
Patrik Stutz <patrik.stutz@gmail.com>
|
||||
Fedor Indutny <fedor.indutny@gmail.com>
|
||||
runner <runner.mei@gmail.com>
|
||||
Alexis Campailla <alexis@janeasystems.com>
|
||||
David Wragg <david@wragg.org>
|
||||
Vinnie Falco <vinnie.falco@gmail.com>
|
||||
Alex Butum <alexbutum@linux.com>
|
||||
Rex Feng <rexfeng@gmail.com>
|
||||
Alex Kocharin <alex@kocharin.ru>
|
||||
Mark Koopman <markmontymark@yahoo.com>
|
||||
Helge Heß <me@helgehess.eu>
|
||||
Alexis La Goutte <alexis.lagoutte@gmail.com>
|
||||
George Miroshnykov <george.miroshnykov@gmail.com>
|
||||
Maciej Małecki <me@mmalecki.com>
|
||||
Marc O'Morain <github.com@marcomorain.com>
|
||||
Jeff Pinner <jpinner@twitter.com>
|
||||
Timothy J Fontaine <tjfontaine@gmail.com>
|
||||
Akagi201 <akagi201@gmail.com>
|
||||
Romain Giraud <giraud.romain@gmail.com>
|
||||
Jay Satiro <raysatiro@yahoo.com>
|
||||
Arne Steen <Arne.Steen@gmx.de>
|
||||
Kjell Schubert <kjell.schubert@gmail.com>
|
||||
Olivier Mengué <dolmen@cpan.org>
|
23
ext/http-parser/LICENSE-MIT
Normal file
23
ext/http-parser/LICENSE-MIT
Normal file
|
@ -0,0 +1,23 @@
|
|||
http_parser.c is based on src/http/ngx_http_parse.c from NGINX copyright
|
||||
Igor Sysoev.
|
||||
|
||||
Additional changes are licensed under the same terms as NGINX and
|
||||
copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
246
ext/http-parser/README.md
Normal file
246
ext/http-parser/README.md
Normal file
|
@ -0,0 +1,246 @@
|
|||
HTTP Parser
|
||||
===========
|
||||
|
||||
[](https://travis-ci.org/nodejs/http-parser)
|
||||
|
||||
This is a parser for HTTP messages written in C. It parses both requests and
|
||||
responses. The parser is designed to be used in performance HTTP
|
||||
applications. It does not make any syscalls nor allocations, it does not
|
||||
buffer data, it can be interrupted at anytime. Depending on your
|
||||
architecture, it only requires about 40 bytes of data per message
|
||||
stream (in a web server that is per connection).
|
||||
|
||||
Features:
|
||||
|
||||
* No dependencies
|
||||
* Handles persistent streams (keep-alive).
|
||||
* Decodes chunked encoding.
|
||||
* Upgrade support
|
||||
* Defends against buffer overflow attacks.
|
||||
|
||||
The parser extracts the following information from HTTP messages:
|
||||
|
||||
* Header fields and values
|
||||
* Content-Length
|
||||
* Request method
|
||||
* Response status code
|
||||
* Transfer-Encoding
|
||||
* HTTP version
|
||||
* Request URL
|
||||
* Message body
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
One `http_parser` object is used per TCP connection. Initialize the struct
|
||||
using `http_parser_init()` and set the callbacks. That might look something
|
||||
like this for a request parser:
|
||||
```c
|
||||
http_parser_settings settings;
|
||||
settings.on_url = my_url_callback;
|
||||
settings.on_header_field = my_header_field_callback;
|
||||
/* ... */
|
||||
|
||||
http_parser *parser = malloc(sizeof(http_parser));
|
||||
http_parser_init(parser, HTTP_REQUEST);
|
||||
parser->data = my_socket;
|
||||
```
|
||||
|
||||
When data is received on the socket execute the parser and check for errors.
|
||||
|
||||
```c
|
||||
size_t len = 80*1024, nparsed;
|
||||
char buf[len];
|
||||
ssize_t recved;
|
||||
|
||||
recved = recv(fd, buf, len, 0);
|
||||
|
||||
if (recved < 0) {
|
||||
/* Handle error. */
|
||||
}
|
||||
|
||||
/* Start up / continue the parser.
|
||||
* Note we pass recved==0 to signal that EOF has been received.
|
||||
*/
|
||||
nparsed = http_parser_execute(parser, &settings, buf, recved);
|
||||
|
||||
if (parser->upgrade) {
|
||||
/* handle new protocol */
|
||||
} else if (nparsed != recved) {
|
||||
/* Handle error. Usually just close the connection. */
|
||||
}
|
||||
```
|
||||
|
||||
HTTP needs to know where the end of the stream is. For example, sometimes
|
||||
servers send responses without Content-Length and expect the client to
|
||||
consume input (for the body) until EOF. To tell http_parser about EOF, give
|
||||
`0` as the fourth parameter to `http_parser_execute()`. Callbacks and errors
|
||||
can still be encountered during an EOF, so one must still be prepared
|
||||
to receive them.
|
||||
|
||||
Scalar valued message information such as `status_code`, `method`, and the
|
||||
HTTP version are stored in the parser structure. This data is only
|
||||
temporally stored in `http_parser` and gets reset on each new message. If
|
||||
this information is needed later, copy it out of the structure during the
|
||||
`headers_complete` callback.
|
||||
|
||||
The parser decodes the transfer-encoding for both requests and responses
|
||||
transparently. That is, a chunked encoding is decoded before being sent to
|
||||
the on_body callback.
|
||||
|
||||
|
||||
The Special Problem of Upgrade
|
||||
------------------------------
|
||||
|
||||
HTTP supports upgrading the connection to a different protocol. An
|
||||
increasingly common example of this is the WebSocket protocol which sends
|
||||
a request like
|
||||
|
||||
GET /demo HTTP/1.1
|
||||
Upgrade: WebSocket
|
||||
Connection: Upgrade
|
||||
Host: example.com
|
||||
Origin: http://example.com
|
||||
WebSocket-Protocol: sample
|
||||
|
||||
followed by non-HTTP data.
|
||||
|
||||
(See [RFC6455](https://tools.ietf.org/html/rfc6455) for more information the
|
||||
WebSocket protocol.)
|
||||
|
||||
To support this, the parser will treat this as a normal HTTP message without a
|
||||
body, issuing both on_headers_complete and on_message_complete callbacks. However
|
||||
http_parser_execute() will stop parsing at the end of the headers and return.
|
||||
|
||||
The user is expected to check if `parser->upgrade` has been set to 1 after
|
||||
`http_parser_execute()` returns. Non-HTTP data begins at the buffer supplied
|
||||
offset by the return value of `http_parser_execute()`.
|
||||
|
||||
|
||||
Callbacks
|
||||
---------
|
||||
|
||||
During the `http_parser_execute()` call, the callbacks set in
|
||||
`http_parser_settings` will be executed. The parser maintains state and
|
||||
never looks behind, so buffering the data is not necessary. If you need to
|
||||
save certain data for later usage, you can do that from the callbacks.
|
||||
|
||||
There are two types of callbacks:
|
||||
|
||||
* notification `typedef int (*http_cb) (http_parser*);`
|
||||
Callbacks: on_message_begin, on_headers_complete, on_message_complete.
|
||||
* data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);`
|
||||
Callbacks: (requests only) on_url,
|
||||
(common) on_header_field, on_header_value, on_body;
|
||||
|
||||
Callbacks must return 0 on success. Returning a non-zero value indicates
|
||||
error to the parser, making it exit immediately.
|
||||
|
||||
For cases where it is necessary to pass local information to/from a callback,
|
||||
the `http_parser` object's `data` field can be used.
|
||||
An example of such a case is when using threads to handle a socket connection,
|
||||
parse a request, and then give a response over that socket. By instantiation
|
||||
of a thread-local struct containing relevant data (e.g. accepted socket,
|
||||
allocated memory for callbacks to write into, etc), a parser's callbacks are
|
||||
able to communicate data between the scope of the thread and the scope of the
|
||||
callback in a threadsafe manner. This allows http-parser to be used in
|
||||
multi-threaded contexts.
|
||||
|
||||
Example:
|
||||
```c
|
||||
typedef struct {
|
||||
socket_t sock;
|
||||
void* buffer;
|
||||
int buf_len;
|
||||
} custom_data_t;
|
||||
|
||||
|
||||
int my_url_callback(http_parser* parser, const char *at, size_t length) {
|
||||
/* access to thread local custom_data_t struct.
|
||||
Use this access save parsed data for later use into thread local
|
||||
buffer, or communicate over socket
|
||||
*/
|
||||
parser->data;
|
||||
...
|
||||
return 0;
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
void http_parser_thread(socket_t sock) {
|
||||
int nparsed = 0;
|
||||
/* allocate memory for user data */
|
||||
custom_data_t *my_data = malloc(sizeof(custom_data_t));
|
||||
|
||||
/* some information for use by callbacks.
|
||||
* achieves thread -> callback information flow */
|
||||
my_data->sock = sock;
|
||||
|
||||
/* instantiate a thread-local parser */
|
||||
http_parser *parser = malloc(sizeof(http_parser));
|
||||
http_parser_init(parser, HTTP_REQUEST); /* initialise parser */
|
||||
/* this custom data reference is accessible through the reference to the
|
||||
parser supplied to callback functions */
|
||||
parser->data = my_data;
|
||||
|
||||
http_parser_settings settings; /* set up callbacks */
|
||||
settings.on_url = my_url_callback;
|
||||
|
||||
/* execute parser */
|
||||
nparsed = http_parser_execute(parser, &settings, buf, recved);
|
||||
|
||||
...
|
||||
/* parsed information copied from callback.
|
||||
can now perform action on data copied into thread-local memory from callbacks.
|
||||
achieves callback -> thread information flow */
|
||||
my_data->buffer;
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
In case you parse HTTP message in chunks (i.e. `read()` request line
|
||||
from socket, parse, read half headers, parse, etc) your data callbacks
|
||||
may be called more than once. Http-parser guarantees that data pointer is only
|
||||
valid for the lifetime of callback. You can also `read()` into a heap allocated
|
||||
buffer to avoid copying memory around if this fits your application.
|
||||
|
||||
Reading headers may be a tricky task if you read/parse headers partially.
|
||||
Basically, you need to remember whether last header callback was field or value
|
||||
and apply the following logic:
|
||||
|
||||
(on_header_field and on_header_value shortened to on_h_*)
|
||||
------------------------ ------------ --------------------------------------------
|
||||
| State (prev. callback) | Callback | Description/action |
|
||||
------------------------ ------------ --------------------------------------------
|
||||
| nothing (first call) | on_h_field | Allocate new buffer and copy callback data |
|
||||
| | | into it |
|
||||
------------------------ ------------ --------------------------------------------
|
||||
| value | on_h_field | New header started. |
|
||||
| | | Copy current name,value buffers to headers |
|
||||
| | | list and allocate new buffer for new name |
|
||||
------------------------ ------------ --------------------------------------------
|
||||
| field | on_h_field | Previous name continues. Reallocate name |
|
||||
| | | buffer and append callback data to it |
|
||||
------------------------ ------------ --------------------------------------------
|
||||
| field | on_h_value | Value for current header started. Allocate |
|
||||
| | | new buffer and copy callback data to it |
|
||||
------------------------ ------------ --------------------------------------------
|
||||
| value | on_h_value | Value continues. Reallocate value buffer |
|
||||
| | | and append callback data to it |
|
||||
------------------------ ------------ --------------------------------------------
|
||||
|
||||
|
||||
Parsing URLs
|
||||
------------
|
||||
|
||||
A simplistic zero-copy URL parser is provided as `http_parser_parse_url()`.
|
||||
Users of this library may wish to use it to parse URLs constructed from
|
||||
consecutive `on_url` callbacks.
|
||||
|
||||
See examples of reading in headers:
|
||||
|
||||
* [partial example](http://gist.github.com/155877) in C
|
||||
* [from http-parser tests](http://github.com/joyent/http-parser/blob/37a0ff8/test.c#L403) in C
|
||||
* [from Node library](http://github.com/joyent/node/blob/842eaf4/src/http.js#L284) in Javascript
|
2469
ext/http-parser/http_parser.c
Normal file
2469
ext/http-parser/http_parser.c
Normal file
File diff suppressed because it is too large
Load diff
362
ext/http-parser/http_parser.h
Normal file
362
ext/http-parser/http_parser.h
Normal file
|
@ -0,0 +1,362 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef http_parser_h
|
||||
#define http_parser_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Also update SONAME in the Makefile whenever you change these. */
|
||||
#define HTTP_PARSER_VERSION_MAJOR 2
|
||||
#define HTTP_PARSER_VERSION_MINOR 7
|
||||
#define HTTP_PARSER_VERSION_PATCH 0
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(_WIN32) && !defined(__MINGW32__) && \
|
||||
(!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__)
|
||||
#include <BaseTsd.h>
|
||||
#include <stddef.h>
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
|
||||
* faster
|
||||
*/
|
||||
#ifndef HTTP_PARSER_STRICT
|
||||
# define HTTP_PARSER_STRICT 1
|
||||
#endif
|
||||
|
||||
/* Maximium header size allowed. If the macro is not defined
|
||||
* before including this header then the default is used. To
|
||||
* change the maximum header size, define the macro in the build
|
||||
* environment (e.g. -DHTTP_MAX_HEADER_SIZE=<value>). To remove
|
||||
* the effective limit on the size of the header, define the macro
|
||||
* to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff)
|
||||
*/
|
||||
#ifndef HTTP_MAX_HEADER_SIZE
|
||||
# define HTTP_MAX_HEADER_SIZE (80*1024)
|
||||
#endif
|
||||
|
||||
typedef struct http_parser http_parser;
|
||||
typedef struct http_parser_settings http_parser_settings;
|
||||
|
||||
|
||||
/* Callbacks should return non-zero to indicate an error. The parser will
|
||||
* then halt execution.
|
||||
*
|
||||
* The one exception is on_headers_complete. In a HTTP_RESPONSE parser
|
||||
* returning '1' from on_headers_complete will tell the parser that it
|
||||
* should not expect a body. This is used when receiving a response to a
|
||||
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
|
||||
* chunked' headers that indicate the presence of a body.
|
||||
*
|
||||
* Returning `2` from on_headers_complete will tell parser that it should not
|
||||
* expect neither a body nor any futher responses on this connection. This is
|
||||
* useful for handling responses to a CONNECT request which may not contain
|
||||
* `Upgrade` or `Connection: upgrade` headers.
|
||||
*
|
||||
* http_data_cb does not return data chunks. It will be called arbitrarily
|
||||
* many times for each string. E.G. you might get 10 callbacks for "on_url"
|
||||
* each providing just a few characters more data.
|
||||
*/
|
||||
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
|
||||
typedef int (*http_cb) (http_parser*);
|
||||
|
||||
|
||||
/* Request Methods */
|
||||
#define HTTP_METHOD_MAP(XX) \
|
||||
XX(0, DELETE, DELETE) \
|
||||
XX(1, GET, GET) \
|
||||
XX(2, HEAD, HEAD) \
|
||||
XX(3, POST, POST) \
|
||||
XX(4, PUT, PUT) \
|
||||
/* pathological */ \
|
||||
XX(5, CONNECT, CONNECT) \
|
||||
XX(6, OPTIONS, OPTIONS) \
|
||||
XX(7, TRACE, TRACE) \
|
||||
/* WebDAV */ \
|
||||
XX(8, COPY, COPY) \
|
||||
XX(9, LOCK, LOCK) \
|
||||
XX(10, MKCOL, MKCOL) \
|
||||
XX(11, MOVE, MOVE) \
|
||||
XX(12, PROPFIND, PROPFIND) \
|
||||
XX(13, PROPPATCH, PROPPATCH) \
|
||||
XX(14, SEARCH, SEARCH) \
|
||||
XX(15, UNLOCK, UNLOCK) \
|
||||
XX(16, BIND, BIND) \
|
||||
XX(17, REBIND, REBIND) \
|
||||
XX(18, UNBIND, UNBIND) \
|
||||
XX(19, ACL, ACL) \
|
||||
/* subversion */ \
|
||||
XX(20, REPORT, REPORT) \
|
||||
XX(21, MKACTIVITY, MKACTIVITY) \
|
||||
XX(22, CHECKOUT, CHECKOUT) \
|
||||
XX(23, MERGE, MERGE) \
|
||||
/* upnp */ \
|
||||
XX(24, MSEARCH, M-SEARCH) \
|
||||
XX(25, NOTIFY, NOTIFY) \
|
||||
XX(26, SUBSCRIBE, SUBSCRIBE) \
|
||||
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
|
||||
/* RFC-5789 */ \
|
||||
XX(28, PATCH, PATCH) \
|
||||
XX(29, PURGE, PURGE) \
|
||||
/* CalDAV */ \
|
||||
XX(30, MKCALENDAR, MKCALENDAR) \
|
||||
/* RFC-2068, section 19.6.1.2 */ \
|
||||
XX(31, LINK, LINK) \
|
||||
XX(32, UNLINK, UNLINK) \
|
||||
|
||||
enum http_method
|
||||
{
|
||||
#define XX(num, name, string) HTTP_##name = num,
|
||||
HTTP_METHOD_MAP(XX)
|
||||
#undef XX
|
||||
};
|
||||
|
||||
|
||||
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
|
||||
|
||||
|
||||
/* Flag values for http_parser.flags field */
|
||||
enum flags
|
||||
{ F_CHUNKED = 1 << 0
|
||||
, F_CONNECTION_KEEP_ALIVE = 1 << 1
|
||||
, F_CONNECTION_CLOSE = 1 << 2
|
||||
, F_CONNECTION_UPGRADE = 1 << 3
|
||||
, F_TRAILING = 1 << 4
|
||||
, F_UPGRADE = 1 << 5
|
||||
, F_SKIPBODY = 1 << 6
|
||||
, F_CONTENTLENGTH = 1 << 7
|
||||
};
|
||||
|
||||
|
||||
/* Map for errno-related constants
|
||||
*
|
||||
* The provided argument should be a macro that takes 2 arguments.
|
||||
*/
|
||||
#define HTTP_ERRNO_MAP(XX) \
|
||||
/* No error */ \
|
||||
XX(OK, "success") \
|
||||
\
|
||||
/* Callback-related errors */ \
|
||||
XX(CB_message_begin, "the on_message_begin callback failed") \
|
||||
XX(CB_url, "the on_url callback failed") \
|
||||
XX(CB_header_field, "the on_header_field callback failed") \
|
||||
XX(CB_header_value, "the on_header_value callback failed") \
|
||||
XX(CB_headers_complete, "the on_headers_complete callback failed") \
|
||||
XX(CB_body, "the on_body callback failed") \
|
||||
XX(CB_message_complete, "the on_message_complete callback failed") \
|
||||
XX(CB_status, "the on_status callback failed") \
|
||||
XX(CB_chunk_header, "the on_chunk_header callback failed") \
|
||||
XX(CB_chunk_complete, "the on_chunk_complete callback failed") \
|
||||
\
|
||||
/* Parsing-related errors */ \
|
||||
XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
|
||||
XX(HEADER_OVERFLOW, \
|
||||
"too many header bytes seen; overflow detected") \
|
||||
XX(CLOSED_CONNECTION, \
|
||||
"data received after completed connection: close message") \
|
||||
XX(INVALID_VERSION, "invalid HTTP version") \
|
||||
XX(INVALID_STATUS, "invalid HTTP status code") \
|
||||
XX(INVALID_METHOD, "invalid HTTP method") \
|
||||
XX(INVALID_URL, "invalid URL") \
|
||||
XX(INVALID_HOST, "invalid host") \
|
||||
XX(INVALID_PORT, "invalid port") \
|
||||
XX(INVALID_PATH, "invalid path") \
|
||||
XX(INVALID_QUERY_STRING, "invalid query string") \
|
||||
XX(INVALID_FRAGMENT, "invalid fragment") \
|
||||
XX(LF_EXPECTED, "LF character expected") \
|
||||
XX(INVALID_HEADER_TOKEN, "invalid character in header") \
|
||||
XX(INVALID_CONTENT_LENGTH, \
|
||||
"invalid character in content-length header") \
|
||||
XX(UNEXPECTED_CONTENT_LENGTH, \
|
||||
"unexpected content-length header") \
|
||||
XX(INVALID_CHUNK_SIZE, \
|
||||
"invalid character in chunk size header") \
|
||||
XX(INVALID_CONSTANT, "invalid constant string") \
|
||||
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
|
||||
XX(STRICT, "strict mode assertion failed") \
|
||||
XX(PAUSED, "parser is paused") \
|
||||
XX(UNKNOWN, "an unknown error occurred")
|
||||
|
||||
|
||||
/* Define HPE_* values for each errno value above */
|
||||
#define HTTP_ERRNO_GEN(n, s) HPE_##n,
|
||||
enum http_errno {
|
||||
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
|
||||
};
|
||||
#undef HTTP_ERRNO_GEN
|
||||
|
||||
|
||||
/* Get an http_errno value from an http_parser */
|
||||
#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
|
||||
|
||||
|
||||
struct http_parser {
|
||||
/** PRIVATE **/
|
||||
unsigned int type : 2; /* enum http_parser_type */
|
||||
unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */
|
||||
unsigned int state : 7; /* enum state from http_parser.c */
|
||||
unsigned int header_state : 7; /* enum header_state from http_parser.c */
|
||||
unsigned int index : 7; /* index into current matcher */
|
||||
unsigned int lenient_http_headers : 1;
|
||||
|
||||
uint32_t nread; /* # bytes read in various scenarios */
|
||||
uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
|
||||
|
||||
/** READ-ONLY **/
|
||||
unsigned short http_major;
|
||||
unsigned short http_minor;
|
||||
unsigned int status_code : 16; /* responses only */
|
||||
unsigned int method : 8; /* requests only */
|
||||
unsigned int http_errno : 7;
|
||||
|
||||
/* 1 = Upgrade header was present and the parser has exited because of that.
|
||||
* 0 = No upgrade header present.
|
||||
* Should be checked when http_parser_execute() returns in addition to
|
||||
* error checking.
|
||||
*/
|
||||
unsigned int upgrade : 1;
|
||||
|
||||
/** PUBLIC **/
|
||||
void *data; /* A pointer to get hook to the "connection" or "socket" object */
|
||||
};
|
||||
|
||||
|
||||
struct http_parser_settings {
|
||||
http_cb on_message_begin;
|
||||
http_data_cb on_url;
|
||||
http_data_cb on_status;
|
||||
http_data_cb on_header_field;
|
||||
http_data_cb on_header_value;
|
||||
http_cb on_headers_complete;
|
||||
http_data_cb on_body;
|
||||
http_cb on_message_complete;
|
||||
/* When on_chunk_header is called, the current chunk length is stored
|
||||
* in parser->content_length.
|
||||
*/
|
||||
http_cb on_chunk_header;
|
||||
http_cb on_chunk_complete;
|
||||
};
|
||||
|
||||
|
||||
enum http_parser_url_fields
|
||||
{ UF_SCHEMA = 0
|
||||
, UF_HOST = 1
|
||||
, UF_PORT = 2
|
||||
, UF_PATH = 3
|
||||
, UF_QUERY = 4
|
||||
, UF_FRAGMENT = 5
|
||||
, UF_USERINFO = 6
|
||||
, UF_MAX = 7
|
||||
};
|
||||
|
||||
|
||||
/* Result structure for http_parser_parse_url().
|
||||
*
|
||||
* Callers should index into field_data[] with UF_* values iff field_set
|
||||
* has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
|
||||
* because we probably have padding left over), we convert any port to
|
||||
* a uint16_t.
|
||||
*/
|
||||
struct http_parser_url {
|
||||
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
|
||||
uint16_t port; /* Converted UF_PORT string */
|
||||
|
||||
struct {
|
||||
uint16_t off; /* Offset into buffer in which field starts */
|
||||
uint16_t len; /* Length of run in buffer */
|
||||
} field_data[UF_MAX];
|
||||
};
|
||||
|
||||
|
||||
/* Returns the library version. Bits 16-23 contain the major version number,
|
||||
* bits 8-15 the minor version number and bits 0-7 the patch level.
|
||||
* Usage example:
|
||||
*
|
||||
* unsigned long version = http_parser_version();
|
||||
* unsigned major = (version >> 16) & 255;
|
||||
* unsigned minor = (version >> 8) & 255;
|
||||
* unsigned patch = version & 255;
|
||||
* printf("http_parser v%u.%u.%u\n", major, minor, patch);
|
||||
*/
|
||||
unsigned long http_parser_version(void);
|
||||
|
||||
void http_parser_init(http_parser *parser, enum http_parser_type type);
|
||||
|
||||
|
||||
/* Initialize http_parser_settings members to 0
|
||||
*/
|
||||
void http_parser_settings_init(http_parser_settings *settings);
|
||||
|
||||
|
||||
/* Executes the parser. Returns number of parsed bytes. Sets
|
||||
* `parser->http_errno` on error. */
|
||||
size_t http_parser_execute(http_parser *parser,
|
||||
const http_parser_settings *settings,
|
||||
const char *data,
|
||||
size_t len);
|
||||
|
||||
|
||||
/* If http_should_keep_alive() in the on_headers_complete or
|
||||
* on_message_complete callback returns 0, then this should be
|
||||
* the last message on the connection.
|
||||
* If you are the server, respond with the "Connection: close" header.
|
||||
* If you are the client, close the connection.
|
||||
*/
|
||||
int http_should_keep_alive(const http_parser *parser);
|
||||
|
||||
/* Returns a string version of the HTTP method. */
|
||||
const char *http_method_str(enum http_method m);
|
||||
|
||||
/* Return a string name of the given error */
|
||||
const char *http_errno_name(enum http_errno err);
|
||||
|
||||
/* Return a string description of the given error */
|
||||
const char *http_errno_description(enum http_errno err);
|
||||
|
||||
/* Initialize all http_parser_url members to 0 */
|
||||
void http_parser_url_init(struct http_parser_url *u);
|
||||
|
||||
/* Parse a URL; return nonzero on failure */
|
||||
int http_parser_parse_url(const char *buf, size_t buflen,
|
||||
int is_connect,
|
||||
struct http_parser_url *u);
|
||||
|
||||
/* Pause or un-pause the parser; a nonzero value pauses */
|
||||
void http_parser_pause(http_parser *parser, int paused);
|
||||
|
||||
/* Checks if this is the final chunk of the body. */
|
||||
int http_body_is_final(const http_parser *parser);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
138
ext/installfiles/linux/zerotier-one.init.rhel6
Executable file
138
ext/installfiles/linux/zerotier-one.init.rhel6
Executable file
|
@ -0,0 +1,138 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# zerotier-one Start the ZeroTier One network virtualization service
|
||||
#
|
||||
# chkconfig: 2345 55 25
|
||||
# description: ZeroTier One allows systems to join and participate in \
|
||||
# ZeroTier virtual networks. See https://www.zerotier.com/
|
||||
#
|
||||
# processname: zerotier-one
|
||||
# config: /var/lib/zerotier-one/identity.public
|
||||
# config: /var/lib/zerotier-one/identity.secret
|
||||
# config: /var/lib/zerotier-one/local.conf
|
||||
# config: /var/lib/zerotier-one/authtoken.secret
|
||||
# pidfile: /var/lib/zerotier-one/zerotier-one.pid
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: zerotier-one
|
||||
# Required-Start: $local_fs $network $syslog
|
||||
# Required-Stop: $local_fs $syslog
|
||||
# Should-Start: $syslog
|
||||
# Should-Stop: $network $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start the ZeroTier One network virtualization service
|
||||
# Description: ZeroTier One allows systems to join and participate in
|
||||
# ZeroTier virtual networks. See https://www.zerotier.com/
|
||||
### END INIT INFO
|
||||
|
||||
# source function library
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
# pull in sysconfig settings
|
||||
[ -f /etc/sysconfig/zerotier-one ] && . /etc/sysconfig/zerotier-one
|
||||
|
||||
RETVAL=0
|
||||
prog="zerotier-one"
|
||||
lockfile=/var/lock/subsys/$prog
|
||||
ZT="/usr/sbin/zerotier-one"
|
||||
PID_FILE=/var/lib/zerotier-one/zerotier-one.pid
|
||||
|
||||
runlevel=$(set -- $(runlevel); eval "echo \$$#" )
|
||||
|
||||
start()
|
||||
{
|
||||
[ -x $ZT ] || exit 5
|
||||
echo -n $"Starting $prog: "
|
||||
$ZT $ZT_OPTIONS -d && success || failure
|
||||
RETVAL=$?
|
||||
[ $RETVAL -eq 0 ] && touch $lockfile
|
||||
echo
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
echo -n $"Stopping $prog: "
|
||||
killproc -p $PID_FILE $ZT
|
||||
RETVAL=$?
|
||||
if [ "x$runlevel" = x0 -o "x$runlevel" = x6 ] ; then
|
||||
trap '' TERM
|
||||
killall $prog 2>/dev/null
|
||||
trap TERM
|
||||
fi
|
||||
[ $RETVAL -eq 0 ] && rm -f $lockfile
|
||||
echo
|
||||
}
|
||||
|
||||
reload()
|
||||
{
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
force_reload() {
|
||||
restart
|
||||
}
|
||||
|
||||
rh_status() {
|
||||
status -p $PID_FILE zerotier-one
|
||||
}
|
||||
|
||||
rh_status_q() {
|
||||
rh_status >/dev/null 2>&1
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
rh_status_q && exit 0
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
if ! rh_status_q; then
|
||||
rm -f $lockfile
|
||||
exit 0
|
||||
fi
|
||||
stop
|
||||
;;
|
||||
restart)
|
||||
restart
|
||||
;;
|
||||
reload)
|
||||
rh_status_q || exit 7
|
||||
reload
|
||||
;;
|
||||
force-reload)
|
||||
force_reload
|
||||
;;
|
||||
condrestart|try-restart)
|
||||
rh_status_q || exit 0
|
||||
if [ -f $lockfile ] ; then
|
||||
do_restart_sanity_check
|
||||
if [ $RETVAL -eq 0 ] ; then
|
||||
stop
|
||||
# avoid race
|
||||
sleep 3
|
||||
start
|
||||
else
|
||||
RETVAL=6
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
status)
|
||||
rh_status
|
||||
RETVAL=$?
|
||||
if [ $RETVAL -eq 3 -a -f $lockfile ] ; then
|
||||
RETVAL=2
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
|
||||
RETVAL=2
|
||||
esac
|
||||
exit $RETVAL
|
985
ext/installfiles/mac/ZeroTier One.pkgproj
Executable file
985
ext/installfiles/mac/ZeroTier One.pkgproj
Executable file
|
@ -0,0 +1,985 @@
|
|||
<?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>PROJECT</key>
|
||||
<dict>
|
||||
<key>PACKAGE_FILES</key>
|
||||
<dict>
|
||||
<key>DEFAULT_INSTALL_LOCATION</key>
|
||||
<string>/</string>
|
||||
<key>HIERARCHY</key>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>80</integer>
|
||||
<key>PATH</key>
|
||||
<string>Utilities</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>80</integer>
|
||||
<key>PATH</key>
|
||||
<string>mac-ui-macgap1-wrapper/bin/ZeroTier One.app</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GID</key>
|
||||
<integer>80</integer>
|
||||
<key>PATH</key>
|
||||
<string>Applications</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>509</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>get-proxy-settings.sh</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>launch.sh</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>../../bin/tap-mac/tap.kext</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>ui/index.html</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>420</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>ui/main.js</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>420</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>ui/react.min.js</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>420</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>ui/simpleajax.min.js</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>420</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>ui/zerotier.css</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>420</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>ui/ztui.min.js</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>420</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>ui</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>2</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>uninstall.sh</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>../../../zerotier-one</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GID</key>
|
||||
<integer>80</integer>
|
||||
<key>PATH</key>
|
||||
<string>One</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>2</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GID</key>
|
||||
<integer>80</integer>
|
||||
<key>PATH</key>
|
||||
<string>ZeroTier</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>2</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GID</key>
|
||||
<integer>80</integer>
|
||||
<key>PATH</key>
|
||||
<string>Application Support</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Automator</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Documentation</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Filesystems</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Frameworks</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Input Methods</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Internet Plug-Ins</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>LaunchAgents</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>com.zerotier.one.plist</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>420</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>LaunchDaemons</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>PreferencePanes</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Preferences</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>80</integer>
|
||||
<key>PATH</key>
|
||||
<string>Printers</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>PrivilegedHelperTools</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>QuickLook</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>QuickTime</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Screen Savers</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Scripts</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Services</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Widgets</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Library</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Extensions</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Library</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>System</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CHILDREN</key>
|
||||
<array/>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>Shared</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>1023</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GID</key>
|
||||
<integer>80</integer>
|
||||
<key>PATH</key>
|
||||
<string>Users</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>/</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
<integer>493</integer>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>UID</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>PAYLOAD_TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>VERSION</key>
|
||||
<integer>3</integer>
|
||||
</dict>
|
||||
<key>PACKAGE_SCRIPTS</key>
|
||||
<dict>
|
||||
<key>POSTINSTALL_PATH</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
<string>postinst.sh</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>PREINSTALL_PATH</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
<string>preinst.sh</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>RESOURCES</key>
|
||||
<array/>
|
||||
</dict>
|
||||
<key>PACKAGE_SETTINGS</key>
|
||||
<dict>
|
||||
<key>AUTHENTICATION</key>
|
||||
<integer>1</integer>
|
||||
<key>CONCLUSION_ACTION</key>
|
||||
<integer>0</integer>
|
||||
<key>IDENTIFIER</key>
|
||||
<string>com.zerotier.pkg.ZeroTierOne</string>
|
||||
<key>OVERWRITE_PERMISSIONS</key>
|
||||
<false/>
|
||||
<key>VERSION</key>
|
||||
<string>1.1.14</string>
|
||||
</dict>
|
||||
<key>PROJECT_COMMENTS</key>
|
||||
<dict>
|
||||
<key>NOTES</key>
|
||||
<data>
|
||||
PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1M
|
||||
IDQuMDEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQv
|
||||
c3RyaWN0LmR0ZCI+CjxodG1sPgo8aGVhZD4KPG1ldGEgaHR0cC1l
|
||||
cXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7
|
||||
IGNoYXJzZXQ9VVRGLTgiPgo8bWV0YSBodHRwLWVxdWl2PSJDb250
|
||||
ZW50LVN0eWxlLVR5cGUiIGNvbnRlbnQ9InRleHQvY3NzIj4KPHRp
|
||||
dGxlPjwvdGl0bGU+CjxtZXRhIG5hbWU9IkdlbmVyYXRvciIgY29u
|
||||
dGVudD0iQ29jb2EgSFRNTCBXcml0ZXIiPgo8bWV0YSBuYW1lPSJD
|
||||
b2NvYVZlcnNpb24iIGNvbnRlbnQ9IjE0MDQuNDciPgo8c3R5bGUg
|
||||
dHlwZT0idGV4dC9jc3MiPgpwLnAxIHttYXJnaW46IDAuMHB4IDAu
|
||||
MHB4IDAuMHB4IDAuMHB4OyBsaW5lLWhlaWdodDogMTQuMHB4OyBm
|
||||
b250OiAxMi4wcHggSGVsdmV0aWNhOyBjb2xvcjogIzAwMDAwMDsg
|
||||
LXdlYmtpdC10ZXh0LXN0cm9rZTogIzAwMDAwMH0Kc3Bhbi5zMSB7
|
||||
Zm9udC1rZXJuaW5nOiBub25lfQo8L3N0eWxlPgo8L2hlYWQ+Cjxi
|
||||
b2R5Pgo8cCBjbGFzcz0icDEiPjxzcGFuIGNsYXNzPSJzMSI+WmVy
|
||||
b1RpZXIgT25lIC0gTmV0d29yayBWaXJ0dWFsaXphdGlvbiBFdmVy
|
||||
eXdoZXJlPC9zcGFuPjwvcD4KPHAgY2xhc3M9InAxIj48c3BhbiBj
|
||||
bGFzcz0iczEiPihjKTIwMTEtMjAxNiBaZXJvVGllciwgSW5jLjwv
|
||||
c3Bhbj48L3A+CjxwIGNsYXNzPSJwMSI+PHNwYW4gY2xhc3M9InMx
|
||||
Ij5jb250YWN0QHplcm90aWVyLmNvbTwvc3Bhbj48L3A+CjxwIGNs
|
||||
YXNzPSJwMSI+PHNwYW4gY2xhc3M9InMxIj48YnI+Cjwvc3Bhbj48
|
||||
L3A+CjxwIGNsYXNzPSJwMSI+PHNwYW4gY2xhc3M9InMxIj5UbyB1
|
||||
bmluc3RhbGwgbWFudWFsbHksIHR5cGUgdGhlIGZvbGxvd2luZyBp
|
||||
biBhIHRlcm1pbmFsIHdpbmRvdzo8L3NwYW4+PC9wPgo8cCBjbGFz
|
||||
cz0icDEiPjxzcGFuIGNsYXNzPSJzMSI+PGJyPgo8L3NwYW4+PC9w
|
||||
Pgo8cCBjbGFzcz0icDEiPjxzcGFuIGNsYXNzPSJzMSI+c3VkbyAi
|
||||
L0xpYnJhcnkvQXBwbGljYXRpb24gU3VwcG9ydC9aZXJvVGllci9P
|
||||
bmUvdW5pbnN0YWxsLnNoIjwvc3Bhbj48L3A+CjwvYm9keT4KPC9o
|
||||
dG1sPgo=
|
||||
</data>
|
||||
</dict>
|
||||
<key>PROJECT_SETTINGS</key>
|
||||
<dict>
|
||||
<key>BUILD_PATH</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
<string>../../..</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>EXCLUDED_FILES</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>PATTERNS_ARRAY</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>REGULAR_EXPRESSION</key>
|
||||
<false/>
|
||||
<key>STRING</key>
|
||||
<string>.DS_Store</string>
|
||||
<key>TYPE</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>PROTECTED</key>
|
||||
<true/>
|
||||
<key>PROXY_NAME</key>
|
||||
<string>Remove .DS_Store files</string>
|
||||
<key>PROXY_TOOLTIP</key>
|
||||
<string>Remove ".DS_Store" files created by the Finder.</string>
|
||||
<key>STATE</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>PATTERNS_ARRAY</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>REGULAR_EXPRESSION</key>
|
||||
<false/>
|
||||
<key>STRING</key>
|
||||
<string>.pbdevelopment</string>
|
||||
<key>TYPE</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>PROTECTED</key>
|
||||
<true/>
|
||||
<key>PROXY_NAME</key>
|
||||
<string>Remove .pbdevelopment files</string>
|
||||
<key>PROXY_TOOLTIP</key>
|
||||
<string>Remove ".pbdevelopment" files created by ProjectBuilder or Xcode.</string>
|
||||
<key>STATE</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>PATTERNS_ARRAY</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>REGULAR_EXPRESSION</key>
|
||||
<false/>
|
||||
<key>STRING</key>
|
||||
<string>CVS</string>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>REGULAR_EXPRESSION</key>
|
||||
<false/>
|
||||
<key>STRING</key>
|
||||
<string>.cvsignore</string>
|
||||
<key>TYPE</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>REGULAR_EXPRESSION</key>
|
||||
<false/>
|
||||
<key>STRING</key>
|
||||
<string>.cvspass</string>
|
||||
<key>TYPE</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>REGULAR_EXPRESSION</key>
|
||||
<false/>
|
||||
<key>STRING</key>
|
||||
<string>.svn</string>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>REGULAR_EXPRESSION</key>
|
||||
<false/>
|
||||
<key>STRING</key>
|
||||
<string>.git</string>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>REGULAR_EXPRESSION</key>
|
||||
<false/>
|
||||
<key>STRING</key>
|
||||
<string>.gitignore</string>
|
||||
<key>TYPE</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>PROTECTED</key>
|
||||
<true/>
|
||||
<key>PROXY_NAME</key>
|
||||
<string>Remove SCM metadata</string>
|
||||
<key>PROXY_TOOLTIP</key>
|
||||
<string>Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems.</string>
|
||||
<key>STATE</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>PATTERNS_ARRAY</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>REGULAR_EXPRESSION</key>
|
||||
<false/>
|
||||
<key>STRING</key>
|
||||
<string>classes.nib</string>
|
||||
<key>TYPE</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>REGULAR_EXPRESSION</key>
|
||||
<false/>
|
||||
<key>STRING</key>
|
||||
<string>designable.db</string>
|
||||
<key>TYPE</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>REGULAR_EXPRESSION</key>
|
||||
<false/>
|
||||
<key>STRING</key>
|
||||
<string>info.nib</string>
|
||||
<key>TYPE</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>PROTECTED</key>
|
||||
<true/>
|
||||
<key>PROXY_NAME</key>
|
||||
<string>Optimize nib files</string>
|
||||
<key>PROXY_TOOLTIP</key>
|
||||
<string>Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles.</string>
|
||||
<key>STATE</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>PATTERNS_ARRAY</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>REGULAR_EXPRESSION</key>
|
||||
<false/>
|
||||
<key>STRING</key>
|
||||
<string>Resources Disabled</string>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>PROTECTED</key>
|
||||
<true/>
|
||||
<key>PROXY_NAME</key>
|
||||
<string>Remove Resources Disabled folders</string>
|
||||
<key>PROXY_TOOLTIP</key>
|
||||
<string>Remove "Resources Disabled" folders.</string>
|
||||
<key>STATE</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SEPARATOR</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NAME</key>
|
||||
<string>ZeroTier One</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>TYPE</key>
|
||||
<integer>1</integer>
|
||||
<key>VERSION</key>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
</plist>
|
22
ext/installfiles/mac/com.zerotier.one.plist
Normal file
22
ext/installfiles/mac/com.zerotier.one.plist
Normal 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>
|
26
ext/installfiles/mac/get-proxy-settings.sh
Executable file
26
ext/installfiles/mac/get-proxy-settings.sh
Executable file
|
@ -0,0 +1,26 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Outputs host and port for system HTTP proxy or zeroes if none or not
|
||||
# configured.
|
||||
|
||||
export PATH=/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin
|
||||
|
||||
enabled=`system_profiler SPNetworkDataType|grep "HTTP Proxy Enabled"|awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'} 2>/dev/null`
|
||||
port=`system_profiler SPNetworkDataType|grep "HTTP Proxy Port"|awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'} 2>/dev/null`
|
||||
serv=`system_profiler SPNetworkDataType|grep "HTTP Proxy Server"|awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'} 2>/dev/null`
|
||||
|
||||
if [ "$enabled" = "Yes" ]; then
|
||||
if [ "$serv" ]; then
|
||||
if [ ! "$port" ]; then
|
||||
port=80
|
||||
fi
|
||||
|
||||
echo $serv $port
|
||||
else
|
||||
echo 0.0.0.0 0
|
||||
fi
|
||||
else
|
||||
echo 0.0.0.0 0
|
||||
fi
|
||||
|
||||
exit 0
|
7
ext/installfiles/mac/launch.sh
Executable file
7
ext/installfiles/mac/launch.sh
Executable file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
zthome="/Library/Application Support/ZeroTier/One"
|
||||
export PATH="$zthome:/bin:/usr/bin:/sbin:/usr/sbin"
|
||||
|
||||
# Launch ZeroTier One (not as daemon... launchd monitors it)
|
||||
exec zerotier-one
|
|
@ -0,0 +1,59 @@
|
|||
<?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>BuildMachineOSBuild</key>
|
||||
<string>15B42</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>ZeroTier One</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>ZeroTierIcon</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.zerotier.ZeroTier-One</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>ZeroTier One</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>7B1005</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>15A278</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.11</string>
|
||||
<key>DTXcode</key>
|
||||
<string>0711</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>7B1005</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.7</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
APPL????
|
Binary file not shown.
|
@ -0,0 +1,13 @@
|
|||
{\rtf1\ansi\ansicpg1252\cocoartf1347\cocoasubrtf570
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\vieww9600\viewh8400\viewkind0
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
|
||||
|
||||
\f0\b\fs24 \cf0 (c)2011-2015 ZeroTier, Inc.\
|
||||
Licensed under the GNU GPLv3\
|
||||
\
|
||||
UI Wrapper MacGap (c) Twitter, Inc.\
|
||||
Licensed under the MIT License\
|
||||
http://macgap.com/\
|
||||
}
|
Binary file not shown.
Binary file not shown.
BIN
ext/installfiles/mac/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/Window.nib
generated
Normal file
BIN
ext/installfiles/mac/mac-ui-macgap1-wrapper/bin/ZeroTier One.app/Contents/Resources/en.lproj/Window.nib
generated
Normal file
Binary file not shown.
|
@ -0,0 +1,187 @@
|
|||
<?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>Resources/ZeroTierIcon.icns</key>
|
||||
<data>
|
||||
430Gd+4+jnim7WxXEEugp6G+Tgk=
|
||||
</data>
|
||||
<key>Resources/en.lproj/Credits.rtf</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
ePttkAH2X1GJ6OL0UhDBAktxB3Y=
|
||||
</data>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Resources/en.lproj/InfoPlist.strings</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
MiLKDDnrUKr4EmuvhS5VQwxHGK8=
|
||||
</data>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Resources/en.lproj/MainMenu.nib</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
8JZXf4/3df3LD+o74Y8WM0dV8io=
|
||||
</data>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Resources/en.lproj/Window.nib</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
aP0mIANPPnnTMmxYlELioz9ZO1I=
|
||||
</data>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>files2</key>
|
||||
<dict>
|
||||
<key>Resources/ZeroTierIcon.icns</key>
|
||||
<data>
|
||||
430Gd+4+jnim7WxXEEugp6G+Tgk=
|
||||
</data>
|
||||
<key>Resources/en.lproj/Credits.rtf</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
ePttkAH2X1GJ6OL0UhDBAktxB3Y=
|
||||
</data>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Resources/en.lproj/InfoPlist.strings</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
MiLKDDnrUKr4EmuvhS5VQwxHGK8=
|
||||
</data>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Resources/en.lproj/MainMenu.nib</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
8JZXf4/3df3LD+o74Y8WM0dV8io=
|
||||
</data>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Resources/en.lproj/Window.nib</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
aP0mIANPPnnTMmxYlELioz9ZO1I=
|
||||
</data>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</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>
|
25
ext/installfiles/mac/mac-ui-macgap1-wrapper/src/LICENSE
Normal file
25
ext/installfiles/mac/mac-ui-macgap1-wrapper/src/LICENSE
Normal file
|
@ -0,0 +1,25 @@
|
|||
MacGap was ported from phonegap-mac, and is under the same license (MIT)
|
||||
|
||||
The MIT License
|
||||
*****************
|
||||
|
||||
Copyright (c) <2012> <Nitobi Software Inc., et. al., >
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
|
@ -0,0 +1,489 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1495814F15C15CCC00E1CFE5 /* Notice.m in Sources */ = {isa = PBXBuildFile; fileRef = 1495814E15C15CCC00E1CFE5 /* Notice.m */; };
|
||||
6F169DA718CC332E005EDDF3 /* Command.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DA618CC332E005EDDF3 /* Command.m */; };
|
||||
6F169DAA18CC35FD005EDDF3 /* CallbackDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DA918CC35FD005EDDF3 /* CallbackDelegate.m */; };
|
||||
6F169DAC18CD8A4A005EDDF3 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F169DAB18CD8A4A005EDDF3 /* JavaScriptCore.framework */; };
|
||||
6F169DB118CD906F005EDDF3 /* MenuItemProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DAE18CD906F005EDDF3 /* MenuItemProxy.m */; };
|
||||
6F169DB218CD906F005EDDF3 /* MenuProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DB018CD906F005EDDF3 /* MenuProxy.m */; };
|
||||
6FD672B618FE618E00C0DAAD /* UserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FD672B518FE618E00C0DAAD /* UserDefaults.m */; };
|
||||
6FD6E4ED18C2D48C00DFFBE6 /* fonts.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */; };
|
||||
88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 88746BED14CCA435001E160E /* JSEventHelper.m */; };
|
||||
88C0646014BDE10A00E4BCE2 /* Window.m in Sources */ = {isa = PBXBuildFile; fileRef = 88C0645F14BDE10A00E4BCE2 /* Window.m */; };
|
||||
88C0646614BDEC5800E4BCE2 /* Window.xib in Resources */ = {isa = PBXBuildFile; fileRef = 88C0646414BDEC5800E4BCE2 /* Window.xib */; };
|
||||
88C0646D14BDF6A600E4BCE2 /* WindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 88C0646C14BDF6A600E4BCE2 /* WindowController.m */; };
|
||||
C14EFCA71B0986AF00894B5F /* ZeroTierIcon.icns in Resources */ = {isa = PBXBuildFile; fileRef = C14EFCA61B0986AF00894B5F /* ZeroTierIcon.icns */; };
|
||||
C1C2B9911AFB0CF10060D7C2 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1C2B9901AFB0CF10060D7C2 /* Security.framework */; };
|
||||
F2B80016179E0FC100B069A8 /* Clipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = F2B80015179E0FC100B069A8 /* Clipboard.m */; };
|
||||
FA32509D14BA813600BF0781 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA32509C14BA813600BF0781 /* WebKit.framework */; };
|
||||
FA3250C314BA85E700BF0781 /* ContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250BC14BA85E700BF0781 /* ContentView.m */; };
|
||||
FA3250C514BA85E700BF0781 /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250BE14BA85E700BF0781 /* Utils.m */; };
|
||||
FA3250C714BA85E700BF0781 /* WebViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250C014BA85E700BF0781 /* WebViewDelegate.m */; };
|
||||
FA3250D314BA860800BF0781 /* App.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250C914BA860800BF0781 /* App.m */; };
|
||||
FA3250D514BA860800BF0781 /* Dock.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250CB14BA860800BF0781 /* Dock.m */; };
|
||||
FA3250D914BA860800BF0781 /* Path.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250CF14BA860800BF0781 /* Path.m */; };
|
||||
FA3250DB14BA860800BF0781 /* Sound.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3250D114BA860800BF0781 /* Sound.m */; };
|
||||
FA3F7742168F70790027B324 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA3F7741168F70780027B324 /* Cocoa.framework */; };
|
||||
FAE451C914BA79C600190544 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = FAE451C714BA79C600190544 /* InfoPlist.strings */; };
|
||||
FAE451CB14BA79C600190544 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FAE451CA14BA79C600190544 /* main.m */; };
|
||||
FAE451CF14BA79C600190544 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = FAE451CD14BA79C600190544 /* Credits.rtf */; };
|
||||
FAE451D214BA79C600190544 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FAE451D114BA79C600190544 /* AppDelegate.m */; };
|
||||
FAE451D514BA79C600190544 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = FAE451D314BA79C600190544 /* MainMenu.xib */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
FA3250DD14BA876F00BF0781 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1495814D15C15CCC00E1CFE5 /* Notice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Notice.h; path = Classes/Commands/Notice.h; sourceTree = "<group>"; };
|
||||
1495814E15C15CCC00E1CFE5 /* Notice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Notice.m; path = Classes/Commands/Notice.m; sourceTree = "<group>"; };
|
||||
6F169DA518CC332E005EDDF3 /* Command.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Command.h; path = Classes/Commands/Command.h; sourceTree = "<group>"; };
|
||||
6F169DA618CC332E005EDDF3 /* Command.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Command.m; path = Classes/Commands/Command.m; sourceTree = "<group>"; };
|
||||
6F169DA818CC35FD005EDDF3 /* CallbackDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CallbackDelegate.h; path = Classes/CallbackDelegate.h; sourceTree = "<group>"; };
|
||||
6F169DA918CC35FD005EDDF3 /* CallbackDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CallbackDelegate.m; path = Classes/CallbackDelegate.m; sourceTree = "<group>"; };
|
||||
6F169DAB18CD8A4A005EDDF3 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||
6F169DAD18CD906F005EDDF3 /* MenuItemProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MenuItemProxy.h; path = Classes/Commands/MenuItemProxy.h; sourceTree = "<group>"; };
|
||||
6F169DAE18CD906F005EDDF3 /* MenuItemProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MenuItemProxy.m; path = Classes/Commands/MenuItemProxy.m; sourceTree = "<group>"; };
|
||||
6F169DAF18CD906F005EDDF3 /* MenuProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MenuProxy.h; path = Classes/Commands/MenuProxy.h; sourceTree = "<group>"; };
|
||||
6F169DB018CD906F005EDDF3 /* MenuProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MenuProxy.m; path = Classes/Commands/MenuProxy.m; sourceTree = "<group>"; };
|
||||
6FD672B418FE618E00C0DAAD /* UserDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UserDefaults.h; path = Classes/Commands/UserDefaults.h; sourceTree = "<group>"; };
|
||||
6FD672B518FE618E00C0DAAD /* UserDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UserDefaults.m; path = Classes/Commands/UserDefaults.m; sourceTree = "<group>"; };
|
||||
6FD6E4EB18C2D48200DFFBE6 /* fonts.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fonts.h; path = Classes/Commands/fonts.h; sourceTree = "<group>"; };
|
||||
6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = fonts.m; path = Classes/Commands/fonts.m; sourceTree = "<group>"; };
|
||||
88746BEC14CCA435001E160E /* JSEventHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSEventHelper.h; path = Classes/JSEventHelper.h; sourceTree = "<group>"; };
|
||||
88746BED14CCA435001E160E /* JSEventHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JSEventHelper.m; path = Classes/JSEventHelper.m; sourceTree = "<group>"; };
|
||||
88C0645E14BDE10A00E4BCE2 /* Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Window.h; path = Classes/Window.h; sourceTree = "<group>"; };
|
||||
88C0645F14BDE10A00E4BCE2 /* Window.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Window.m; path = Classes/Window.m; sourceTree = "<group>"; };
|
||||
88C0646514BDEC5800E4BCE2 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/Window.xib; sourceTree = "<group>"; };
|
||||
88C0646B14BDF6A600E4BCE2 /* WindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowController.h; sourceTree = "<group>"; };
|
||||
88C0646C14BDF6A600E4BCE2 /* WindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WindowController.m; sourceTree = "<group>"; };
|
||||
C14EFCA61B0986AF00894B5F /* ZeroTierIcon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = ZeroTierIcon.icns; path = ../../../../artwork/ZeroTierIcon.icns; sourceTree = "<group>"; };
|
||||
C1C2B9901AFB0CF10060D7C2 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
||||
F2B80014179E0FC100B069A8 /* Clipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Clipboard.h; sourceTree = "<group>"; };
|
||||
F2B80015179E0FC100B069A8 /* Clipboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Clipboard.m; sourceTree = "<group>"; };
|
||||
FA32509C14BA813600BF0781 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
|
||||
FA3250BA14BA85E700BF0781 /* Constants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Constants.h; path = Classes/Constants.h; sourceTree = "<group>"; };
|
||||
FA3250BB14BA85E700BF0781 /* ContentView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ContentView.h; path = Classes/ContentView.h; sourceTree = "<group>"; };
|
||||
FA3250BC14BA85E700BF0781 /* ContentView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ContentView.m; path = Classes/ContentView.m; sourceTree = "<group>"; };
|
||||
FA3250BD14BA85E700BF0781 /* Utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = Classes/Utils.h; sourceTree = "<group>"; };
|
||||
FA3250BE14BA85E700BF0781 /* Utils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Utils.m; path = Classes/Utils.m; sourceTree = "<group>"; };
|
||||
FA3250BF14BA85E700BF0781 /* WebViewDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WebViewDelegate.h; path = Classes/WebViewDelegate.h; sourceTree = "<group>"; };
|
||||
FA3250C014BA85E700BF0781 /* WebViewDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = WebViewDelegate.m; path = Classes/WebViewDelegate.m; sourceTree = "<group>"; };
|
||||
FA3250C814BA860800BF0781 /* App.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = App.h; path = Classes/Commands/App.h; sourceTree = "<group>"; };
|
||||
FA3250C914BA860800BF0781 /* App.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = App.m; path = Classes/Commands/App.m; sourceTree = "<group>"; };
|
||||
FA3250CA14BA860800BF0781 /* Dock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Dock.h; path = Classes/Commands/Dock.h; sourceTree = "<group>"; };
|
||||
FA3250CB14BA860800BF0781 /* Dock.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Dock.m; path = Classes/Commands/Dock.m; sourceTree = "<group>"; };
|
||||
FA3250CE14BA860800BF0781 /* Path.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Path.h; path = Classes/Commands/Path.h; sourceTree = "<group>"; };
|
||||
FA3250CF14BA860800BF0781 /* Path.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Path.m; path = Classes/Commands/Path.m; sourceTree = "<group>"; };
|
||||
FA3250D014BA860800BF0781 /* Sound.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Sound.h; path = Classes/Commands/Sound.h; sourceTree = "<group>"; };
|
||||
FA3250D114BA860800BF0781 /* Sound.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Sound.m; path = Classes/Commands/Sound.m; sourceTree = "<group>"; };
|
||||
FA3F7741168F70780027B324 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; };
|
||||
FAE451BA14BA79C600190544 /* ZeroTier One.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ZeroTier One.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FAE451BE14BA79C600190544 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
FAE451C114BA79C600190544 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
FAE451C214BA79C600190544 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
FAE451C314BA79C600190544 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
FAE451C614BA79C600190544 /* MacGap-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MacGap-Info.plist"; sourceTree = "<group>"; };
|
||||
FAE451C814BA79C600190544 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
FAE451CA14BA79C600190544 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
FAE451CC14BA79C600190544 /* MacGap-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MacGap-Prefix.pch"; sourceTree = "<group>"; };
|
||||
FAE451CE14BA79C600190544 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
|
||||
FAE451D014BA79C600190544 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
FAE451D114BA79C600190544 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
FAE451D414BA79C600190544 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
FAE451B714BA79C600190544 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C1C2B9911AFB0CF10060D7C2 /* Security.framework in Frameworks */,
|
||||
6F169DAC18CD8A4A005EDDF3 /* JavaScriptCore.framework in Frameworks */,
|
||||
FA3F7742168F70790027B324 /* Cocoa.framework in Frameworks */,
|
||||
FA32509D14BA813600BF0781 /* WebKit.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
FA3250E014BA87B800BF0781 /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FA3250E114BA87DD00BF0781 /* Commands */,
|
||||
FA3250BA14BA85E700BF0781 /* Constants.h */,
|
||||
6F169DA818CC35FD005EDDF3 /* CallbackDelegate.h */,
|
||||
6F169DA918CC35FD005EDDF3 /* CallbackDelegate.m */,
|
||||
FA3250BB14BA85E700BF0781 /* ContentView.h */,
|
||||
FA3250BC14BA85E700BF0781 /* ContentView.m */,
|
||||
FA3250BF14BA85E700BF0781 /* WebViewDelegate.h */,
|
||||
FA3250C014BA85E700BF0781 /* WebViewDelegate.m */,
|
||||
88C0646B14BDF6A600E4BCE2 /* WindowController.h */,
|
||||
88C0646C14BDF6A600E4BCE2 /* WindowController.m */,
|
||||
);
|
||||
name = Classes;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FA3250E114BA87DD00BF0781 /* Commands */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6F169DA518CC332E005EDDF3 /* Command.h */,
|
||||
6F169DA618CC332E005EDDF3 /* Command.m */,
|
||||
1495814D15C15CCC00E1CFE5 /* Notice.h */,
|
||||
1495814E15C15CCC00E1CFE5 /* Notice.m */,
|
||||
FA3250CA14BA860800BF0781 /* Dock.h */,
|
||||
FA3250CB14BA860800BF0781 /* Dock.m */,
|
||||
6FD6E4EB18C2D48200DFFBE6 /* fonts.h */,
|
||||
6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */,
|
||||
FA3250BD14BA85E700BF0781 /* Utils.h */,
|
||||
FA3250BE14BA85E700BF0781 /* Utils.m */,
|
||||
6FD672B418FE618E00C0DAAD /* UserDefaults.h */,
|
||||
6FD672B518FE618E00C0DAAD /* UserDefaults.m */,
|
||||
FA3250CE14BA860800BF0781 /* Path.h */,
|
||||
FA3250CF14BA860800BF0781 /* Path.m */,
|
||||
FA3250D014BA860800BF0781 /* Sound.h */,
|
||||
FA3250D114BA860800BF0781 /* Sound.m */,
|
||||
FA3250C814BA860800BF0781 /* App.h */,
|
||||
FA3250C914BA860800BF0781 /* App.m */,
|
||||
6F169DAD18CD906F005EDDF3 /* MenuItemProxy.h */,
|
||||
6F169DAE18CD906F005EDDF3 /* MenuItemProxy.m */,
|
||||
6F169DAF18CD906F005EDDF3 /* MenuProxy.h */,
|
||||
6F169DB018CD906F005EDDF3 /* MenuProxy.m */,
|
||||
88C0645E14BDE10A00E4BCE2 /* Window.h */,
|
||||
88C0645F14BDE10A00E4BCE2 /* Window.m */,
|
||||
88746BEC14CCA435001E160E /* JSEventHelper.h */,
|
||||
88746BED14CCA435001E160E /* JSEventHelper.m */,
|
||||
F2B80014179E0FC100B069A8 /* Clipboard.h */,
|
||||
F2B80015179E0FC100B069A8 /* Clipboard.m */,
|
||||
);
|
||||
name = Commands;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FAE451AF14BA79C600190544 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FA3F7741168F70780027B324 /* Cocoa.framework */,
|
||||
FAE451C414BA79C600190544 /* MacGap */,
|
||||
FAE451BD14BA79C600190544 /* Frameworks */,
|
||||
FAE451BB14BA79C600190544 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FAE451BB14BA79C600190544 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FAE451BA14BA79C600190544 /* ZeroTier One.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FAE451BD14BA79C600190544 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C1C2B9901AFB0CF10060D7C2 /* Security.framework */,
|
||||
6F169DAB18CD8A4A005EDDF3 /* JavaScriptCore.framework */,
|
||||
FA32509C14BA813600BF0781 /* WebKit.framework */,
|
||||
FAE451BE14BA79C600190544 /* Cocoa.framework */,
|
||||
FAE451C014BA79C600190544 /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FAE451C014BA79C600190544 /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FAE451C114BA79C600190544 /* AppKit.framework */,
|
||||
FAE451C214BA79C600190544 /* CoreData.framework */,
|
||||
FAE451C314BA79C600190544 /* Foundation.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FAE451C414BA79C600190544 /* MacGap */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FA3250E014BA87B800BF0781 /* Classes */,
|
||||
FAE451D014BA79C600190544 /* AppDelegate.h */,
|
||||
FAE451D114BA79C600190544 /* AppDelegate.m */,
|
||||
C14EFCA61B0986AF00894B5F /* ZeroTierIcon.icns */,
|
||||
FAE451D314BA79C600190544 /* MainMenu.xib */,
|
||||
88C0646414BDEC5800E4BCE2 /* Window.xib */,
|
||||
FAE451C514BA79C600190544 /* Supporting Files */,
|
||||
);
|
||||
path = MacGap;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FAE451C514BA79C600190544 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FAE451C614BA79C600190544 /* MacGap-Info.plist */,
|
||||
FAE451C714BA79C600190544 /* InfoPlist.strings */,
|
||||
FAE451CA14BA79C600190544 /* main.m */,
|
||||
FAE451CC14BA79C600190544 /* MacGap-Prefix.pch */,
|
||||
FAE451CD14BA79C600190544 /* Credits.rtf */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
FAE451B914BA79C600190544 /* MacGap */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = FAE451D814BA79C600190544 /* Build configuration list for PBXNativeTarget "MacGap" */;
|
||||
buildPhases = (
|
||||
FAE451B814BA79C600190544 /* Resources */,
|
||||
FAE451B614BA79C600190544 /* Sources */,
|
||||
FAE451B714BA79C600190544 /* Frameworks */,
|
||||
FA3250DD14BA876F00BF0781 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = MacGap;
|
||||
productName = MacGap;
|
||||
productReference = FAE451BA14BA79C600190544 /* ZeroTier One.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
FAE451B114BA79C600190544 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0710;
|
||||
ORGANIZATIONNAME = Twitter;
|
||||
};
|
||||
buildConfigurationList = FAE451B414BA79C600190544 /* Build configuration list for PBXProject "MacGap" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = FAE451AF14BA79C600190544;
|
||||
productRefGroup = FAE451BB14BA79C600190544 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
FAE451B914BA79C600190544 /* MacGap */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
FAE451B814BA79C600190544 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C14EFCA71B0986AF00894B5F /* ZeroTierIcon.icns in Resources */,
|
||||
FAE451C914BA79C600190544 /* InfoPlist.strings in Resources */,
|
||||
FAE451CF14BA79C600190544 /* Credits.rtf in Resources */,
|
||||
FAE451D514BA79C600190544 /* MainMenu.xib in Resources */,
|
||||
88C0646614BDEC5800E4BCE2 /* Window.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
FAE451B614BA79C600190544 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6F169DAA18CC35FD005EDDF3 /* CallbackDelegate.m in Sources */,
|
||||
FA3250D314BA860800BF0781 /* App.m in Sources */,
|
||||
FA3250D514BA860800BF0781 /* Dock.m in Sources */,
|
||||
FA3250D914BA860800BF0781 /* Path.m in Sources */,
|
||||
FA3250DB14BA860800BF0781 /* Sound.m in Sources */,
|
||||
FA3250C314BA85E700BF0781 /* ContentView.m in Sources */,
|
||||
FA3250C514BA85E700BF0781 /* Utils.m in Sources */,
|
||||
FA3250C714BA85E700BF0781 /* WebViewDelegate.m in Sources */,
|
||||
FAE451CB14BA79C600190544 /* main.m in Sources */,
|
||||
6F169DB118CD906F005EDDF3 /* MenuItemProxy.m in Sources */,
|
||||
FAE451D214BA79C600190544 /* AppDelegate.m in Sources */,
|
||||
6F169DA718CC332E005EDDF3 /* Command.m in Sources */,
|
||||
6FD672B618FE618E00C0DAAD /* UserDefaults.m in Sources */,
|
||||
88C0646014BDE10A00E4BCE2 /* Window.m in Sources */,
|
||||
6F169DB218CD906F005EDDF3 /* MenuProxy.m in Sources */,
|
||||
88C0646D14BDF6A600E4BCE2 /* WindowController.m in Sources */,
|
||||
6FD6E4ED18C2D48C00DFFBE6 /* fonts.m in Sources */,
|
||||
88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */,
|
||||
1495814F15C15CCC00E1CFE5 /* Notice.m in Sources */,
|
||||
F2B80016179E0FC100B069A8 /* Clipboard.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
88C0646414BDEC5800E4BCE2 /* Window.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
88C0646514BDEC5800E4BCE2 /* en */,
|
||||
);
|
||||
name = Window.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FAE451C714BA79C600190544 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
FAE451C814BA79C600190544 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FAE451CD14BA79C600190544 /* Credits.rtf */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
FAE451CE14BA79C600190544 /* en */,
|
||||
);
|
||||
name = Credits.rtf;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FAE451D314BA79C600190544 /* MainMenu.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
FAE451D414BA79C600190544 /* en */,
|
||||
);
|
||||
name = MainMenu.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
FAE451D614BA79C600190544 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_VERSION = "";
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "ZeroTier One";
|
||||
SDKROOT = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
FAE451D714BA79C600190544 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_VERSION = "";
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
PRODUCT_NAME = "ZeroTier One";
|
||||
SDKROOT = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
FAE451D914BA79C600190544 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
|
||||
CLANG_CXX_LIBRARY = "compiler-default";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/MacGap\"",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "MacGap/MacGap-Prefix.pch";
|
||||
GCC_VERSION = "";
|
||||
INFOPLIST_FILE = "MacGap/MacGap-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.zerotier.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "ZeroTier One";
|
||||
SDKROOT = macosx;
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
FAE451DA14BA79C600190544 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
|
||||
CLANG_CXX_LIBRARY = "compiler-default";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/MacGap\"",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "MacGap/MacGap-Prefix.pch";
|
||||
GCC_VERSION = "";
|
||||
INFOPLIST_FILE = "MacGap/MacGap-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.zerotier.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "ZeroTier One";
|
||||
SDKROOT = macosx;
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
FAE451B414BA79C600190544 /* Build configuration list for PBXProject "MacGap" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FAE451D614BA79C600190544 /* Debug */,
|
||||
FAE451D714BA79C600190544 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
FAE451D814BA79C600190544 /* Build configuration list for PBXNativeTarget "MacGap" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FAE451D914BA79C600190544 /* Debug */,
|
||||
FAE451DA14BA79C600190544 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = FAE451B114BA79C600190544 /* Project object */;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:MacGap.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,41 @@
|
|||
<?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>IDESourceControlProjectFavoriteDictionaryKey</key>
|
||||
<false/>
|
||||
<key>IDESourceControlProjectIdentifier</key>
|
||||
<string>4D486E78-E297-4CC3-AAAE-1A58EDAC87E6</string>
|
||||
<key>IDESourceControlProjectName</key>
|
||||
<string>MacGap</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>ABA3617E9F0148F844A82502F0D808DE6591AA97</key>
|
||||
<string>http://adam.ierymenko@git.int.zerotier.com/zerotier/zerotierone</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectPath</key>
|
||||
<string>ext/mac-ui-macgap1-wrapper/src/MacGap.xcodeproj</string>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>ABA3617E9F0148F844A82502F0D808DE6591AA97</key>
|
||||
<string>../../../../..</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectURL</key>
|
||||
<string>http://adam.ierymenko@git.int.zerotier.com/zerotier/zerotierone</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
<integer>111</integer>
|
||||
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||
<string>ABA3617E9F0148F844A82502F0D808DE6591AA97</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>ABA3617E9F0148F844A82502F0D808DE6591AA97</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>ZeroTierOne</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
|
@ -0,0 +1,10 @@
|
|||
<?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>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
|
||||
<true/>
|
||||
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
|
@ -0,0 +1,10 @@
|
|||
<?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>IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
|
||||
<true/>
|
||||
<key>IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// AppDelegate.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Alex MacCaw on 08/01/2012.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "Classes/ContentView.h"
|
||||
|
||||
#import "WindowController.h"
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@property (retain, nonatomic) WindowController *windowController;
|
||||
|
||||
@end
|
|
@ -0,0 +1,159 @@
|
|||
//
|
||||
// AppDelegate.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Alex MacCaw on 08/01/2012.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
@synthesize windowController;
|
||||
|
||||
- (void) applicationWillFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
}
|
||||
|
||||
-(BOOL)applicationShouldHandleReopen:(NSApplication*)application
|
||||
hasVisibleWindows:(BOOL)visibleWindows{
|
||||
if(!visibleWindows){
|
||||
[self.windowController.window makeKeyAndOrderFront: nil];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||
char buf[16384],userAuthTokenPath[4096];
|
||||
struct stat systemAuthTokenStat,userAuthTokenStat;
|
||||
|
||||
FILE *pf = fopen("/Library/Application Support/ZeroTier/One/zerotier-one.port","r");
|
||||
long port = 9993; // default
|
||||
if (pf) {
|
||||
long n = fread(buf,1,sizeof(buf)-1,pf);
|
||||
if (n > 0) {
|
||||
buf[n] = (char)0;
|
||||
port = strtol(buf,(char **)0,10);
|
||||
}
|
||||
fclose(pf);
|
||||
}
|
||||
|
||||
char url[16384];
|
||||
memset(url,0,sizeof(url));
|
||||
|
||||
const char *homeDir = getenv("HOME");
|
||||
if (homeDir) {
|
||||
snprintf(userAuthTokenPath,sizeof(userAuthTokenPath),"%s/Library/Application Support/ZeroTier/One/authtoken.secret",homeDir);
|
||||
|
||||
bool userAuthTokenOutOfDate = false;
|
||||
memset(&systemAuthTokenStat,0,sizeof(systemAuthTokenStat));
|
||||
memset(&userAuthTokenStat,0,sizeof(userAuthTokenStat));
|
||||
if (stat("/Library/Application Support/ZeroTier/One/authtoken.secret",&systemAuthTokenStat) == 0) {
|
||||
if (stat(userAuthTokenPath,&userAuthTokenStat) == 0) {
|
||||
if (userAuthTokenStat.st_mtimespec.tv_sec < systemAuthTokenStat.st_mtimespec.tv_sec)
|
||||
userAuthTokenOutOfDate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!userAuthTokenOutOfDate) {
|
||||
pf = fopen(userAuthTokenPath,"r");
|
||||
if (pf) {
|
||||
long n = fread(buf,1,sizeof(buf)-1,pf);
|
||||
if (n > 0) {
|
||||
buf[n] = (char)0;
|
||||
snprintf(url,sizeof(url),"http://127.0.0.1:%ld/index.html?authToken=%s",port,buf);
|
||||
}
|
||||
fclose(pf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!url[0]) {
|
||||
// Create authorization reference
|
||||
OSStatus status;
|
||||
AuthorizationRef authorizationRef;
|
||||
|
||||
// AuthorizationCreate and pass NULL as the initial
|
||||
// AuthorizationRights set so that the AuthorizationRef gets created
|
||||
// successfully, and then later call AuthorizationCopyRights to
|
||||
// determine or extend the allowable rights.
|
||||
// http://developer.apple.com/qa/qa2001/qa1172.html
|
||||
status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
|
||||
if (status != errAuthorizationSuccess)
|
||||
{
|
||||
NSLog(@"Error Creating Initial Authorization: %d", status);
|
||||
return;
|
||||
}
|
||||
|
||||
// kAuthorizationRightExecute == "system.privilege.admin"
|
||||
AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0};
|
||||
AuthorizationRights rights = {1, &right};
|
||||
AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |
|
||||
kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;
|
||||
|
||||
// Call AuthorizationCopyRights to determine or extend the allowable rights.
|
||||
status = AuthorizationCopyRights(authorizationRef, &rights, NULL, flags, NULL);
|
||||
if (status != errAuthorizationSuccess)
|
||||
{
|
||||
NSLog(@"Copy Rights Unsuccessful: %d", status);
|
||||
return;
|
||||
}
|
||||
|
||||
// use rm tool with -rf
|
||||
char *tool = "/bin/cat";
|
||||
char *args[] = {"/Library/Application Support/ZeroTier/One/authtoken.secret", NULL};
|
||||
FILE *pipe = NULL;
|
||||
|
||||
status = AuthorizationExecuteWithPrivileges(authorizationRef, tool, kAuthorizationFlagDefaults, args, &pipe);
|
||||
if (status != errAuthorizationSuccess)
|
||||
{
|
||||
NSLog(@"Error: %d", status);
|
||||
}
|
||||
|
||||
if (pipe) {
|
||||
long n = (long)fread(buf,1,sizeof(buf)-1,pipe);
|
||||
if (n > 0) {
|
||||
buf[n] = (char)0;
|
||||
snprintf(url,sizeof(url),"http://127.0.0.1:%ld/index.html?authToken=%s",port,buf);
|
||||
|
||||
if (homeDir) {
|
||||
snprintf(userAuthTokenPath,sizeof(userAuthTokenPath),"%s/Library/Application Support/ZeroTier",homeDir);
|
||||
mkdir(userAuthTokenPath,0755);
|
||||
snprintf(userAuthTokenPath,sizeof(userAuthTokenPath),"%s/Library/Application Support/ZeroTier/One",homeDir);
|
||||
mkdir(userAuthTokenPath,0755);
|
||||
snprintf(userAuthTokenPath,sizeof(userAuthTokenPath),"%s/Library/Application Support/ZeroTier/One/authtoken.secret",homeDir);
|
||||
pf = fopen(userAuthTokenPath,"w");
|
||||
if (pf) {
|
||||
fwrite(buf,1,strlen(buf),pf);
|
||||
fclose(pf);
|
||||
chmod(userAuthTokenPath,0600);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(pipe);
|
||||
}
|
||||
|
||||
// The only way to guarantee that a credential acquired when you
|
||||
// request a right is not shared with other authorization instances is
|
||||
// to destroy the credential. To do so, call the AuthorizationFree
|
||||
// function with the flag kAuthorizationFlagDestroyRights.
|
||||
// http://developer.apple.com/documentation/Security/Conceptual/authorization_concepts/02authconcepts/chapter_2_section_7.html
|
||||
status = AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights);
|
||||
}
|
||||
|
||||
NSString *urlStr = [[NSString alloc] initWithCString:url];
|
||||
self.windowController = [[WindowController alloc] initWithURL: urlStr];
|
||||
[self.windowController showWindow: [NSApplication sharedApplication].delegate];
|
||||
self.windowController.contentView.webView.alphaValue = 1.0;
|
||||
self.windowController.contentView.alphaValue = 1.0;
|
||||
[self.windowController showWindow:self];
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// CallbackDelegate.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Joe Hildebrand on 1/10/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Command.h"
|
||||
|
||||
@interface CallbackDelegate : Command {
|
||||
}
|
||||
|
||||
@property JSObjectRef callback;
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext forCallback:(WebScriptObject*)aCallback;
|
||||
- (id) call;
|
||||
- (id) callWithParams:(id)firstOrNil, ... NS_REQUIRES_NIL_TERMINATION;
|
||||
|
||||
@end
|
|
@ -0,0 +1,168 @@
|
|||
//
|
||||
// CallbackDelegate.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Joe Hildebrand on 1/10/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CallbackDelegate.h"
|
||||
#import <JavaScriptCore/JavaScript.h>
|
||||
|
||||
@implementation CallbackDelegate
|
||||
|
||||
@synthesize callback;
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext forCallback:(WebScriptObject*)aCallback
|
||||
{
|
||||
if (!aCallback)
|
||||
return nil;
|
||||
if ([aCallback isKindOfClass:[WebUndefined class]])
|
||||
return nil;
|
||||
|
||||
self = [super initWithContext:aContext];
|
||||
if (!self)
|
||||
return nil;
|
||||
|
||||
callback = [aCallback JSObject];
|
||||
JSValueProtect(context, callback);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (callback)
|
||||
{
|
||||
JSValueUnprotect(context, callback);
|
||||
callback = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (id) objectFromValue:(JSValueRef)val
|
||||
{
|
||||
JSStringRef jstr;
|
||||
NSString *rets;
|
||||
|
||||
switch(JSValueGetType(context, val))
|
||||
{
|
||||
case kJSTypeUndefined:
|
||||
case kJSTypeNull:
|
||||
return nil;
|
||||
case kJSTypeBoolean:
|
||||
return [NSNumber numberWithBool:JSValueToBoolean(context, val)];
|
||||
case kJSTypeNumber:
|
||||
return [NSNumber numberWithDouble:JSValueToNumber(context, val, NULL)];
|
||||
case kJSTypeString:
|
||||
jstr = JSValueToStringCopy(context, val, NULL);
|
||||
size_t sz = JSStringGetMaximumUTF8CStringSize(jstr);
|
||||
char *buf = (char*)malloc(sz);
|
||||
JSStringGetUTF8CString(jstr, buf, sz);
|
||||
rets = [NSString stringWithUTF8String:buf];
|
||||
free(buf);
|
||||
return rets;
|
||||
case kJSTypeObject:
|
||||
// TODO: dictionary or something
|
||||
return nil;
|
||||
default:
|
||||
NSAssert(false, @"Invalid JavaScript type");
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (JSValueRef) valueFromObject:(id)obj
|
||||
{
|
||||
JSValueRef val = nil;
|
||||
if (!obj)
|
||||
{
|
||||
val = JSValueMakeNull(context);
|
||||
}
|
||||
else if ([obj isKindOfClass:[NSString class]])
|
||||
{
|
||||
JSStringRef jstr = JSStringCreateWithUTF8CString([obj UTF8String]);
|
||||
val = JSValueMakeString(context, jstr);
|
||||
JSStringRelease(jstr);
|
||||
}
|
||||
else if ([obj isKindOfClass:[NSNumber class]])
|
||||
{
|
||||
val = JSValueMakeNumber(context, [obj doubleValue]);
|
||||
}
|
||||
else if ([obj isKindOfClass:[NSDictionary class]])
|
||||
{
|
||||
JSObjectRef o = JSObjectMake(context, NULL, NULL);
|
||||
for (NSString *key in obj)
|
||||
{
|
||||
JSStringRef kstr = JSStringCreateWithUTF8CString([key UTF8String]);
|
||||
JSValueRef v = [self valueFromObject:[obj objectForKey:key]];
|
||||
|
||||
JSObjectSetProperty(context, o, kstr, v, kJSPropertyAttributeNone, NULL);
|
||||
JSStringRelease(kstr);
|
||||
}
|
||||
val = o;
|
||||
}
|
||||
else if ([obj isKindOfClass:[NSArray class]])
|
||||
{
|
||||
NSUInteger pcount = [obj count];
|
||||
JSValueRef jsArgs[pcount];
|
||||
NSUInteger i=0;
|
||||
for (id v in obj)
|
||||
{
|
||||
jsArgs[i++] = [self valueFromObject:v];
|
||||
}
|
||||
val = JSObjectMakeArray(context, pcount, jsArgs, NULL);
|
||||
}
|
||||
else if ([obj isKindOfClass:[NSDate class]])
|
||||
{
|
||||
NSTimeInterval secs = [obj timeIntervalSince1970];
|
||||
JSValueRef jsArgs[1];
|
||||
// call the Date(milliseconds) constructor in JS
|
||||
jsArgs[0] = JSValueMakeNumber(context, secs * 1000.0);
|
||||
val = JSObjectMakeDate(context, 1, jsArgs, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Warning: unknown object type for: %@", obj);
|
||||
val = JSValueMakeUndefined(context);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
- (id) call
|
||||
{
|
||||
NSAssert(callback, @"Callback required");
|
||||
if (!JSObjectIsFunction(context, callback))
|
||||
return nil;
|
||||
|
||||
JSValueRef jsArgs[0];
|
||||
JSValueRef ret = JSObjectCallAsFunction(context, callback, NULL, 0, jsArgs, NULL);
|
||||
return [self objectFromValue:ret];
|
||||
}
|
||||
|
||||
- (id) callWithParams:(id)firstOrNil, ...
|
||||
{
|
||||
NSAssert(callback, @"Callback required");
|
||||
if (!JSObjectIsFunction(context, callback))
|
||||
return nil;
|
||||
NSUInteger pcount = 0;
|
||||
id p;
|
||||
va_list args;
|
||||
va_start(args, firstOrNil);
|
||||
for (p=firstOrNil; p; p=va_arg(args, id))
|
||||
{
|
||||
pcount++;
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
JSValueRef jsArgs[pcount];
|
||||
NSUInteger j = 0;
|
||||
va_start(args, firstOrNil);
|
||||
for (p=firstOrNil; p; p=va_arg(args, id))
|
||||
{
|
||||
jsArgs[j++] = [self valueFromObject:p];
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
JSValueRef ret = JSObjectCallAsFunction(context, callback, NULL, j, jsArgs, NULL);
|
||||
return [self objectFromValue:ret];
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,21 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "WindowController.h"
|
||||
|
||||
@interface App : NSObject {
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) WebView *webView;
|
||||
|
||||
- (id) initWithWebView:(WebView *)view;
|
||||
|
||||
- (void) terminate;
|
||||
- (void) activate;
|
||||
- (void) hide;
|
||||
- (void) unhide;
|
||||
- (void) beep;
|
||||
- (void) bounce;
|
||||
- (void) setCustomUserAgent:(NSString *)userAgentString;
|
||||
- (NSNumber*) systemIdleTime;
|
||||
@end
|
|
@ -0,0 +1,128 @@
|
|||
#import "App.h"
|
||||
|
||||
#import "JSEventHelper.h"
|
||||
|
||||
@implementation App
|
||||
|
||||
@synthesize webView;
|
||||
|
||||
- (id) initWithWebView:(WebView *) view{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
self.webView = view;
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
|
||||
selector: @selector(receiveSleepNotification:)
|
||||
name: NSWorkspaceWillSleepNotification object: NULL];
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
|
||||
selector: @selector(receiveWakeNotification:)
|
||||
name: NSWorkspaceDidWakeNotification object: NULL];
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
|
||||
selector: @selector(receiveActivateNotification:)
|
||||
name: NSWorkspaceDidActivateApplicationNotification object: NULL];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) terminate {
|
||||
[NSApp terminate:nil];
|
||||
}
|
||||
|
||||
- (void) activate {
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
||||
- (void) hide {
|
||||
[NSApp hide:nil];
|
||||
}
|
||||
|
||||
- (void) unhide {
|
||||
[NSApp unhide:nil];
|
||||
}
|
||||
|
||||
- (void)beep {
|
||||
NSBeep();
|
||||
}
|
||||
|
||||
- (void) bounce {
|
||||
[NSApp requestUserAttention:NSInformationalRequest];
|
||||
}
|
||||
|
||||
- (void)setCustomUserAgent:(NSString *)userAgentString {
|
||||
[self.webView setCustomUserAgent: userAgentString];
|
||||
}
|
||||
|
||||
- (void) open:(NSString*)url {
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
|
||||
}
|
||||
|
||||
- (void) launch:(NSString *)name {
|
||||
[[NSWorkspace sharedWorkspace] launchApplication:name];
|
||||
}
|
||||
|
||||
- (void)receiveSleepNotification:(NSNotification*)note{
|
||||
[JSEventHelper triggerEvent:@"sleep" forWebView:self.webView];
|
||||
}
|
||||
|
||||
- (void) receiveWakeNotification:(NSNotification*)note{
|
||||
[JSEventHelper triggerEvent:@"wake" forWebView:self.webView];
|
||||
}
|
||||
|
||||
- (void) receiveActivateNotification:(NSNotification*)notification{
|
||||
NSDictionary* userInfo = [notification userInfo];
|
||||
NSRunningApplication* runningApplication = [userInfo objectForKey:NSWorkspaceApplicationKey];
|
||||
if (runningApplication) {
|
||||
NSMutableDictionary* applicationDidGetFocusDict = [[NSMutableDictionary alloc] initWithCapacity:2];
|
||||
[applicationDidGetFocusDict setObject:runningApplication.localizedName
|
||||
forKey:@"localizedName"];
|
||||
[applicationDidGetFocusDict setObject:[runningApplication.bundleURL absoluteString]
|
||||
forKey:@"bundleURL"];
|
||||
|
||||
[JSEventHelper triggerEvent:@"appActivated" withArgs:applicationDidGetFocusDict forWebView:self.webView];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
To get the elapsed time since the previous input event—keyboard, mouse, or tablet—specify kCGAnyInputEventType.
|
||||
*/
|
||||
- (NSNumber*)systemIdleTime {
|
||||
CFTimeInterval timeSinceLastEvent = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateHIDSystemState, kCGAnyInputEventType);
|
||||
|
||||
return [NSNumber numberWithDouble:timeSinceLastEvent];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector
|
||||
{
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(open:)) {
|
||||
result = @"open";
|
||||
} else if (selector == @selector(launch:)) {
|
||||
result = @"launch";
|
||||
} else if (selector == @selector(setCustomUserAgent:)) {
|
||||
result = @"setCustomUserAgent";
|
||||
} else if (selector == @selector(systemIdleTime)) {
|
||||
result = @"systemIdleTime";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// Command.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Joe Hildebrand on 1/10/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Webkit/WebScriptObject.h>
|
||||
|
||||
@interface Command : NSObject {
|
||||
JSContextRef context;
|
||||
}
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext;
|
||||
|
||||
@end
|
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// Command.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Joe Hildebrand on 1/10/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Command.h"
|
||||
#import <JavaScriptCore/JSContextRef.h>
|
||||
|
||||
@implementation Command
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext {
|
||||
self = [super init];
|
||||
if (!self)
|
||||
return nil;
|
||||
context = aContext;
|
||||
JSGlobalContextRetain((JSGlobalContextRef)context);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (context)
|
||||
JSGlobalContextRelease((JSGlobalContextRef)context);
|
||||
}
|
||||
@end
|
|
@ -0,0 +1,11 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Dock : NSObject {
|
||||
|
||||
}
|
||||
- (void) setBadge:(NSString*)value;
|
||||
- (NSString *) badge;
|
||||
|
||||
@property (readwrite, copy) NSString *badge;
|
||||
|
||||
@end
|
|
@ -0,0 +1,31 @@
|
|||
#import "Dock.h"
|
||||
|
||||
@implementation Dock
|
||||
|
||||
@synthesize badge;
|
||||
|
||||
- (void) setBadge:(NSString *)value
|
||||
{
|
||||
NSDockTile *tile = [[NSApplication sharedApplication] dockTile];
|
||||
[tile setBadgeLabel:value];
|
||||
}
|
||||
|
||||
- (NSString *) badge
|
||||
{
|
||||
NSDockTile *tile = [[NSApplication sharedApplication] dockTile];
|
||||
return [tile badgeLabel];
|
||||
}
|
||||
|
||||
#pragma mark WebScripting Protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// MenuItemProxy.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Joe Hildebrand on 1/15/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Command.h"
|
||||
#import "CallbackDelegate.h"
|
||||
|
||||
@class MenuProxy;
|
||||
|
||||
@interface MenuItemProxy : Command {
|
||||
NSMenuItem *item;
|
||||
CallbackDelegate *callback;
|
||||
}
|
||||
|
||||
+ (MenuItemProxy*) proxyWithContext:(JSContextRef)aContext andMenuItem:(NSMenuItem*)anItem;
|
||||
|
||||
- (MenuProxy*)addSubmenu;
|
||||
|
||||
- (void) remove;
|
||||
- (void) setCallback:(WebScriptObject*)aCallback;
|
||||
- (void) setKey:(NSString*)keyCommand;
|
||||
- (void) setTitle:(NSString*)title;
|
||||
- (void) enable;
|
||||
- (void) disable;
|
||||
- (MenuProxy*)submenu;
|
||||
|
||||
@end
|
|
@ -0,0 +1,150 @@
|
|||
//
|
||||
// MenuItemProxy.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Joe Hildebrand on 1/15/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MenuItemProxy.h"
|
||||
#import "MenuProxy.h"
|
||||
|
||||
@implementation MenuItemProxy
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext andMenuItem:(NSMenuItem*)anItem
|
||||
{
|
||||
NSAssert(anItem, @"anItem required");
|
||||
self = [super initWithContext:aContext];
|
||||
if (!self)
|
||||
return nil;
|
||||
item = anItem;
|
||||
item.representedObject = self;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (MenuItemProxy*) proxyWithContext:(JSContextRef)aContext andMenuItem:(NSMenuItem*)anItem
|
||||
{
|
||||
MenuItemProxy *proxy = [anItem representedObject];
|
||||
if (proxy)
|
||||
{
|
||||
NSLog(@"MIP Cache hit");
|
||||
NSAssert([proxy class] == [MenuItemProxy class], @"Bad proxy");
|
||||
return proxy;
|
||||
}
|
||||
return [[MenuItemProxy alloc] initWithContext:aContext andMenuItem:anItem];
|
||||
}
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
return [item description];
|
||||
}
|
||||
|
||||
- (MenuProxy*)addSubmenu
|
||||
{
|
||||
NSMenu *s = [item submenu];
|
||||
if (!s)
|
||||
{
|
||||
s = [[NSMenu alloc] initWithTitle:@"FFFFFFOOOOO"];
|
||||
[item setSubmenu:s];
|
||||
}
|
||||
return [MenuProxy proxyWithContext:context andMenu:s];
|
||||
}
|
||||
|
||||
- (void) remove
|
||||
{
|
||||
NSMenu *menu = [item menu];
|
||||
[menu removeItem:item];
|
||||
}
|
||||
|
||||
- (void)callCallback:(id)sender
|
||||
{
|
||||
[callback callWithParams:[sender title], nil];
|
||||
}
|
||||
|
||||
- (void) setCallback:(WebScriptObject*)aCallback
|
||||
{
|
||||
NSAssert(item, @"item required");
|
||||
callback = [[CallbackDelegate alloc] initWithContext:context forCallback:aCallback];
|
||||
[item setAction:@selector(callCallback:)];
|
||||
[item setTarget:self];
|
||||
}
|
||||
|
||||
- (void)setKey:(NSString*)keyCommand
|
||||
{
|
||||
NSString *aKey = [MenuProxy getKeyFromString:keyCommand];
|
||||
[item setKeyEquivalent:aKey];
|
||||
|
||||
NSUInteger modifiers = [MenuProxy getModifiersFromString:keyCommand];
|
||||
[item setKeyEquivalentModifierMask:modifiers];
|
||||
}
|
||||
|
||||
- (void) setTitle:(NSString*)title
|
||||
{
|
||||
[item setTitle:title];
|
||||
}
|
||||
|
||||
- (MenuProxy*)submenu;
|
||||
{
|
||||
// TODO: make this work as a property
|
||||
NSMenu *s = [item submenu];
|
||||
if (!s)
|
||||
return nil;
|
||||
return [MenuProxy proxyWithContext:context andMenu:s];
|
||||
}
|
||||
|
||||
- (void) enable
|
||||
{
|
||||
[item setEnabled:YES];
|
||||
}
|
||||
|
||||
- (void) disable
|
||||
{
|
||||
[item setEnabled:NO];
|
||||
}
|
||||
|
||||
#pragma mark WebScripting protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return [self webScriptNameForSelector:selector] == nil;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector
|
||||
{
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(addSubmenu)) {
|
||||
result = @"addSubmenu";
|
||||
}
|
||||
else if (selector == @selector(remove)) {
|
||||
result = @"remove";
|
||||
}
|
||||
else if (selector == @selector(setCallback:)) {
|
||||
result = @"setCallback";
|
||||
}
|
||||
else if (selector == @selector(setKey:)) {
|
||||
result = @"setKey";
|
||||
}
|
||||
else if (selector == @selector(setTitle:)) {
|
||||
result = @"setTitle";
|
||||
}
|
||||
else if (selector == @selector(submenu)) {
|
||||
result = @"submenu";
|
||||
}
|
||||
else if (selector == @selector(enable)) {
|
||||
result = @"enable";
|
||||
}
|
||||
else if (selector == @selector(disable)) {
|
||||
result = @"disable";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// MenuProxy.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Joe Hildebrand on 1/14/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Command.h"
|
||||
|
||||
@class MenuItemProxy;
|
||||
|
||||
@interface MenuProxy : Command {
|
||||
NSMenu *menu;
|
||||
}
|
||||
|
||||
+ (MenuProxy*)proxyWithContext:(JSContextRef)aContext andMenu:(NSMenu*)aMenu;
|
||||
|
||||
- (MenuItemProxy*)addItemWithTitle:(NSString*)title
|
||||
keyEquivalent:(NSString*)aKey
|
||||
callback:(WebScriptObject*)aCallback
|
||||
atIndex:(NSInteger)index;
|
||||
|
||||
- (MenuItemProxy*)addSeparator;
|
||||
- (MenuItemProxy*)itemForKey:(id)key;
|
||||
- (MenuProxy*)removeItem:(id)key;
|
||||
|
||||
+ (NSString*)getKeyFromString:(NSString*)keyCommand;
|
||||
+ (NSUInteger*)getModifiersFromString:(NSString*)keyCommand;
|
||||
|
||||
@end
|
|
@ -0,0 +1,233 @@
|
|||
//
|
||||
// MenuProxy.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Joe Hildebrand on 1/14/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <objc/runtime.h>
|
||||
#import <JavaScriptCore/JavaScript.h>
|
||||
|
||||
#import "MenuProxy.h"
|
||||
#import "MenuItemProxy.h"
|
||||
|
||||
static char REPRESENTED_OBJECT;
|
||||
|
||||
@interface NSMenu (represented)
|
||||
@property (strong) id representedObject;
|
||||
@end
|
||||
|
||||
@implementation NSMenu (represented)
|
||||
|
||||
- (id) representedObject
|
||||
{
|
||||
return objc_getAssociatedObject(self, &REPRESENTED_OBJECT);
|
||||
}
|
||||
|
||||
- (void) setRepresentedObject:(id)representedObject
|
||||
{
|
||||
objc_setAssociatedObject(self,
|
||||
&REPRESENTED_OBJECT,
|
||||
representedObject,
|
||||
OBJC_ASSOCIATION_RETAIN);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MenuProxy
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext andMenu:(NSMenu*)aMenu
|
||||
{
|
||||
self = [super initWithContext:aContext];
|
||||
if (!self)
|
||||
return nil;
|
||||
menu = aMenu;
|
||||
menu.representedObject = self;
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (MenuProxy*)proxyWithContext:(JSContextRef)aContext andMenu:(NSMenu*)aMenu
|
||||
{
|
||||
// singleton-ish.
|
||||
MenuProxy *ret = [aMenu representedObject];
|
||||
if (ret)
|
||||
{
|
||||
NSLog(@"MP cache hit");
|
||||
return ret;
|
||||
}
|
||||
return [[MenuProxy alloc] initWithContext:aContext andMenu:aMenu];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
menu.representedObject = nil;
|
||||
}
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
return [menu description];
|
||||
}
|
||||
|
||||
static BOOL isNullish(id o)
|
||||
{
|
||||
if (!o)
|
||||
return YES;
|
||||
if ([o isKindOfClass:[WebUndefined class]])
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (MenuItemProxy*)addItemWithTitle:(NSString*)title
|
||||
keyEquivalent:(NSString*)keyCommand
|
||||
callback:(WebScriptObject*)aCallback
|
||||
atIndex:(NSInteger)index
|
||||
{
|
||||
if (isNullish(title))
|
||||
title = @"";
|
||||
|
||||
NSString *aKey = [MenuProxy getKeyFromString:keyCommand];
|
||||
NSMenuItem *item = nil;
|
||||
|
||||
if(index) {
|
||||
item = [menu insertItemWithTitle:title action:nil keyEquivalent:aKey atIndex:index ];
|
||||
} else {
|
||||
item = [menu addItemWithTitle:title action:nil keyEquivalent:aKey ];
|
||||
|
||||
}
|
||||
|
||||
// Set the modifiers.
|
||||
NSUInteger modifiers = [MenuProxy getModifiersFromString:keyCommand];
|
||||
[item setKeyEquivalentModifierMask:modifiers];
|
||||
|
||||
if(!menu.supermenu) {
|
||||
NSMenu *s = [[NSMenu alloc] initWithTitle:title];
|
||||
[item setSubmenu:s];
|
||||
}
|
||||
|
||||
MenuItemProxy *mip = [MenuItemProxy proxyWithContext:context andMenuItem:item];
|
||||
if (!isNullish(aCallback))
|
||||
[mip setCallback:aCallback];
|
||||
|
||||
|
||||
return mip;
|
||||
}
|
||||
|
||||
+ (NSString*)getKeyFromString:(NSString*)keyCommand {
|
||||
if (isNullish(keyCommand))
|
||||
keyCommand = @"";
|
||||
|
||||
// Obtain the key (if there are modifiers, it will be the last character).
|
||||
NSString *aKey = @"";
|
||||
if ([keyCommand length] > 0) {
|
||||
aKey = [keyCommand substringFromIndex:[keyCommand length] - 1];
|
||||
}
|
||||
|
||||
return aKey;
|
||||
}
|
||||
|
||||
+ (NSUInteger*)getModifiersFromString:(NSString*)keyCommand {
|
||||
// aKeys may optionally specify one or more modifiers.
|
||||
NSUInteger modifiers = 0;
|
||||
|
||||
if ([keyCommand rangeOfString:@"caps"].location != NSNotFound) modifiers += NSAlphaShiftKeyMask;
|
||||
if ([keyCommand rangeOfString:@"shift"].location != NSNotFound) modifiers += NSShiftKeyMask;
|
||||
if ([keyCommand rangeOfString:@"cmd"].location != NSNotFound) modifiers += NSCommandKeyMask;
|
||||
if ([keyCommand rangeOfString:@"ctrl"].location != NSNotFound) modifiers += NSControlKeyMask;
|
||||
if ([keyCommand rangeOfString:@"opt"].location != NSNotFound) modifiers += NSAlternateKeyMask;
|
||||
if ([keyCommand rangeOfString:@"alt"].location != NSNotFound) modifiers += NSAlternateKeyMask;
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
- (MenuItemProxy*)addSeparator
|
||||
{
|
||||
NSMenuItem *sep = [NSMenuItem separatorItem];
|
||||
[menu addItem:sep];
|
||||
return [MenuItemProxy proxyWithContext:context andMenuItem:sep];
|
||||
}
|
||||
|
||||
- (MenuItemProxy*)itemForKey:(id)key
|
||||
{
|
||||
if (isNullish(key))
|
||||
return nil;
|
||||
NSMenuItem *item = nil;
|
||||
if ([key isKindOfClass:[NSNumber class]])
|
||||
{
|
||||
item = [menu itemAtIndex:[key intValue]];
|
||||
}
|
||||
else if ([key isKindOfClass:[NSString class]])
|
||||
{
|
||||
item = [menu itemWithTitle:key];
|
||||
if (!item)
|
||||
{
|
||||
// Try again, with ... appended. e.g. "Save..."
|
||||
item = [menu itemWithTitle:
|
||||
[key stringByAppendingString:@"\u2026"]];
|
||||
}
|
||||
}
|
||||
if (!item)
|
||||
return nil;
|
||||
|
||||
return [MenuItemProxy proxyWithContext:context andMenuItem:item];
|
||||
}
|
||||
|
||||
- (MenuProxy*)removeItem:(id)key
|
||||
{
|
||||
if (isNullish(key))
|
||||
return nil;
|
||||
|
||||
NSMenuItem *item = nil;
|
||||
if ([key isKindOfClass:[NSNumber class]])
|
||||
{
|
||||
item = [menu itemAtIndex:[key intValue]];
|
||||
}
|
||||
else if ([key isKindOfClass:[NSString class]])
|
||||
{
|
||||
item = [menu itemWithTitle:key];
|
||||
if (!item)
|
||||
{
|
||||
// Try again, with ... appended. e.g. "Save..."
|
||||
item = [menu itemWithTitle:
|
||||
[key stringByAppendingString:@"\u2026"]];
|
||||
}
|
||||
}
|
||||
if (!item)
|
||||
return nil;
|
||||
|
||||
[menu removeItem:item];
|
||||
return [MenuProxy proxyWithContext:context andMenu:menu];
|
||||
}
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return [self webScriptNameForSelector:selector] == nil;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector
|
||||
{
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(addItemWithTitle:keyEquivalent:callback:atIndex:)) {
|
||||
result = @"addItem";
|
||||
}
|
||||
else if (selector == @selector(addSeparator)) {
|
||||
result = @"addSeparator";
|
||||
}
|
||||
else if (selector == @selector(itemForKey:)) {
|
||||
result = @"getItem";
|
||||
}
|
||||
else if (selector == @selector(removeItem:)) {
|
||||
result = @"removeMenu";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Notice.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Christian Sullivan on 7/26/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "WindowController.h"
|
||||
|
||||
#define APP_NOTICE_NOTIFICATION @"Notice"
|
||||
|
||||
@interface Notice : NSObject <NSUserNotificationCenterDelegate> {
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) WebView *webView;
|
||||
|
||||
- (id) initWithWebView:(WebView *)view;
|
||||
- (void) notify:(NSDictionary*)message;
|
||||
- (void) close:(NSString*)notificationId;
|
||||
+ (BOOL) available;
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
//
|
||||
// Notice.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Christian Sullivan on 7/26/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Notice.h"
|
||||
|
||||
#import "JSEventHelper.h"
|
||||
|
||||
@implementation Notice
|
||||
|
||||
- (id) initWithWebView:(WebView*)view
|
||||
{
|
||||
if(self = [super init]) {
|
||||
self.webView = view;
|
||||
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) notify:(NSDictionary *)message {
|
||||
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
||||
[notification setTitle:[message valueForKey:@"title"]];
|
||||
[notification setInformativeText:[message valueForKey:@"content"]];
|
||||
[notification setDeliveryDate:[NSDate dateWithTimeInterval:0 sinceDate:[NSDate date]]];
|
||||
BOOL playSound = true; // optional parameter, false only when {sound: false}
|
||||
@try {
|
||||
NSNumber *s = [message valueForKey:@"sound"];
|
||||
if ([[s className] isEqual: @"__NSCFBoolean"]) {
|
||||
playSound = [s boolValue];
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
}
|
||||
if (playSound) {
|
||||
[notification setSoundName:NSUserNotificationDefaultSoundName];
|
||||
}
|
||||
NSString *id = @""; // optional, needed for close
|
||||
@try {
|
||||
id = [message valueForKey:@"id"];
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
}
|
||||
[notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:id, @"id", nil]];
|
||||
NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
|
||||
[center scheduleNotification:notification];
|
||||
}
|
||||
|
||||
// close all notifications with id == notificationId or close all notifications if notificationId == "*"
|
||||
- (void) close:(NSString*)notificationId {
|
||||
NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
|
||||
for(NSUserNotification * deliveredNote in center.deliveredNotifications) {
|
||||
if ([notificationId isEqualToString:@"*"] || [deliveredNote.userInfo[@"id"] isEqualToString:notificationId]) {
|
||||
[center removeDeliveredNotification: deliveredNote];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL) available {
|
||||
if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)])
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
|
||||
{
|
||||
NSString *notificationId = [notification.userInfo valueForKey:@"id"];
|
||||
[JSEventHelper triggerEvent:@"macgap.notify.activated" forDetail:notificationId forWebView:self.webView];
|
||||
}
|
||||
|
||||
#pragma mark WebScripting Protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
BOOL result = YES;
|
||||
if (selector == @selector(notify:))
|
||||
result = NO;
|
||||
if (selector == @selector(close:))
|
||||
result = NO;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector
|
||||
{
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(notify:)) {
|
||||
result = @"notify";
|
||||
}
|
||||
if (selector == @selector(close:)) {
|
||||
result = @"close";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// right now exclude all properties (eg keys)
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,21 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Path : NSObject {
|
||||
|
||||
}
|
||||
|
||||
- (NSString *) application;
|
||||
- (NSString *) resource;
|
||||
- (NSString *) documents;
|
||||
- (NSString *) library;
|
||||
- (NSString *) home;
|
||||
- (NSString *) temp;
|
||||
|
||||
@property (readonly,copy) NSString* application;
|
||||
@property (readonly,copy) NSString* resource;
|
||||
@property (readonly,copy) NSString* documents;
|
||||
@property (readonly,copy) NSString* library;
|
||||
@property (readonly,copy) NSString* home;
|
||||
@property (readonly,copy) NSString* temp;
|
||||
|
||||
@end
|
|
@ -0,0 +1,53 @@
|
|||
#import "Path.h"
|
||||
|
||||
@implementation Path
|
||||
|
||||
@synthesize application;
|
||||
@synthesize resource;
|
||||
@synthesize documents;
|
||||
@synthesize library;
|
||||
@synthesize home;
|
||||
@synthesize temp;
|
||||
|
||||
- (NSString *)application {
|
||||
return [[NSBundle mainBundle] bundlePath];
|
||||
}
|
||||
|
||||
- (NSString *)resource {
|
||||
return [[NSBundle mainBundle] resourcePath];
|
||||
}
|
||||
|
||||
- (NSString *)documents {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
return [paths objectAtIndex:0];
|
||||
}
|
||||
|
||||
- (NSString *)library {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
|
||||
NSLog( @"%@", paths );
|
||||
return [paths objectAtIndex:0];
|
||||
}
|
||||
|
||||
- (NSString *)home {
|
||||
return NSHomeDirectory();
|
||||
}
|
||||
|
||||
- (NSString *)temp {
|
||||
return NSTemporaryDirectory();
|
||||
}
|
||||
|
||||
#pragma mark WebScripting Protocol
|
||||
|
||||
/* checks whether a selector is acceptable to be called from JavaScript */
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
// right now exclude all properties (eg keys)
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,17 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
#import "Command.h"
|
||||
#import "CallbackDelegate.h"
|
||||
|
||||
|
||||
@interface Sound : Command {
|
||||
|
||||
}
|
||||
|
||||
// pending callbacks for sounds being played, to keep
|
||||
// ARC from freeing them too early
|
||||
@property (nonatomic, strong) NSMutableSet *pending;
|
||||
|
||||
- (void) play:(NSString*)file onComplete:(WebScriptObject*)callback;
|
||||
- (void) playSystem:(NSString*)name onComplete:(WebScriptObject*)callback;
|
||||
|
||||
@end
|
|
@ -0,0 +1,97 @@
|
|||
#import "Sound.h"
|
||||
|
||||
|
||||
@interface PlayDelegate : CallbackDelegate <NSSoundDelegate> {
|
||||
}
|
||||
|
||||
@property (nonatomic, weak) Sound *sound;
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext
|
||||
forCallback:(WebScriptObject*)aCallback
|
||||
withSound:(Sound*)aSound;
|
||||
@end
|
||||
|
||||
@implementation PlayDelegate
|
||||
|
||||
@synthesize sound;
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext
|
||||
forCallback:(WebScriptObject*)aCallback
|
||||
withSound:(Sound*)aSound
|
||||
{
|
||||
self = [super initWithContext:aContext forCallback:aCallback];
|
||||
if (!self)
|
||||
return nil;
|
||||
sound = aSound;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)sound:(NSSound *)aSound didFinishPlaying:(BOOL)finishedPlaying {
|
||||
[self callWithParams:[aSound name], nil];
|
||||
[sound.pending removeObject:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation Sound
|
||||
|
||||
@synthesize pending;
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext {
|
||||
self = [super initWithContext:aContext];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
pending = [NSMutableSet new];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) playSound:(NSSound*)sound onComplete:(WebScriptObject*)callback {
|
||||
if (callback != (id)[WebUndefined undefined]) {
|
||||
PlayDelegate *d = [[PlayDelegate alloc] initWithContext:context
|
||||
forCallback:callback
|
||||
withSound:self];
|
||||
[pending addObject:d];
|
||||
[sound setDelegate:d];
|
||||
}
|
||||
[sound play];
|
||||
}
|
||||
|
||||
- (void) play:(NSString*)file onComplete:(WebScriptObject*)callback {
|
||||
NSURL* fileUrl = [NSURL fileURLWithPath:[[Utils sharedInstance] pathForResource:file]];
|
||||
DebugNSLog(@"Sound file:%@", [fileUrl description]);
|
||||
|
||||
NSSound* sound = [[NSSound alloc] initWithContentsOfURL:fileUrl byReference:YES];
|
||||
[self playSound:sound onComplete:callback];
|
||||
}
|
||||
|
||||
- (void) playSystem:(NSString*)name onComplete:(WebScriptObject*)callback {
|
||||
NSSound *systemSound = [NSSound soundNamed:name];
|
||||
[self playSound:systemSound onComplete:callback];
|
||||
}
|
||||
|
||||
#pragma mark WebScripting Protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector {
|
||||
return [self webScriptNameForSelector:selector] == nil;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name {
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector {
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(play:onComplete:)) {
|
||||
result = @"play";
|
||||
}
|
||||
else if (selector == @selector(playSystem:onComplete:)) {
|
||||
result = @"playSystem";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// UserDefaults.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Jeff Hanbury on 16/04/2014.
|
||||
// Copyright (c) 2014 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "WindowController.h"
|
||||
|
||||
@interface UserDefaults : NSObject
|
||||
|
||||
@property (nonatomic, retain) WebView *webView;
|
||||
|
||||
- (id) initWithWebView:(WebView *)view;
|
||||
- (NSString*) getMyDefaults;
|
||||
- (NSDictionary*) myDefaultsDictionary;
|
||||
- (void) removeObjectForKey:(NSString*)key;
|
||||
- (NSArray*) getUserDefaultsKeys;
|
||||
|
||||
- (NSString*) addPrefix:(NSString*)key;
|
||||
|
||||
- (void) setString:(NSString*)key withValue:(NSString*)value;
|
||||
- (NSString*) getString:(NSString*)key;
|
||||
|
||||
- (void) setInteger:(NSString*)key withValue:(NSString*)value;
|
||||
- (NSNumber*) getInteger:(NSString*)key;
|
||||
|
||||
- (void) setBool:(NSString*)key withValue:(NSString*)value;
|
||||
- (NSNumber*) getBool:(NSString*)key;
|
||||
|
||||
- (void) setFloat:(NSString*)key withValue:(NSString*)value;
|
||||
- (NSNumber*) getFloat:(NSString*)key;
|
||||
|
||||
// Could also be implemented:
|
||||
//– setObject:forKey:
|
||||
//– setDouble:forKey:
|
||||
//– setURL:forKey:
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
//
|
||||
// UserDefaults.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Jeff Hanbury on 16/04/2014.
|
||||
// Copyright (c) 2014 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UserDefaults.h"
|
||||
#import "JSEventHelper.h"
|
||||
|
||||
@interface UserDefaults() {
|
||||
|
||||
}
|
||||
|
||||
-(void) setupNotificationCenter;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation UserDefaults
|
||||
|
||||
- (id) initWithWebView:(WebView *) view{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
self.webView = view;
|
||||
[self setupNotificationCenter];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
-(void) setupNotificationCenter{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(defaultsChanged:)
|
||||
name:NSUserDefaultsDidChangeNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)defaultsChanged:(NSNotification *)notification {
|
||||
NSDictionary* returnDict = [self myDefaultsDictionary];
|
||||
[JSEventHelper triggerEvent:@"userDefaultsChanged" withArgs:returnDict forWebView:self.webView];
|
||||
}
|
||||
|
||||
- (NSString*) getMyDefaults {
|
||||
NSDictionary* myDefaults = [self myDefaultsDictionary];
|
||||
|
||||
return [[Utils sharedInstance] convertDictionaryToJSON:myDefaults];
|
||||
}
|
||||
|
||||
- (NSDictionary*) myDefaultsDictionary {
|
||||
NSString* prefix = [kWebScriptNamespace stringByAppendingString:@"_"];
|
||||
NSMutableDictionary* returnDict = [[NSMutableDictionary alloc] init];
|
||||
|
||||
// Get the user defaults.
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
// Build up a dictionary containing just the items beginning with our
|
||||
// prefix.
|
||||
for (NSString* key in [self getUserDefaultsKeys]) {
|
||||
if ([key hasPrefix:prefix]) {
|
||||
id val = [defaults valueForKey:key];
|
||||
[returnDict setObject:val forKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
return returnDict;
|
||||
}
|
||||
|
||||
- (NSArray*) getUserDefaultsKeys {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
return [[prefs dictionaryRepresentation] allKeys];
|
||||
}
|
||||
|
||||
- (void) removeObjectForKey:(NSString*)key {
|
||||
NSString* prefixedKey;
|
||||
prefixedKey = [self addPrefix:key];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:prefixedKey];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
|
||||
// Check we have a standard prefix for JS-modified keys, for security purposes.
|
||||
// If not, add it. This stops JavaScript from ever being able to modify keys
|
||||
// it did not create.
|
||||
- (NSString*) addPrefix:(NSString*)key {
|
||||
NSString* prefix;
|
||||
prefix = [kWebScriptNamespace stringByAppendingString:@"_"];
|
||||
|
||||
if (![key hasPrefix:prefix]) {
|
||||
key = [prefix stringByAppendingString:key];
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
// String
|
||||
|
||||
- (void) setString:(NSString*)key withValue:(NSString*)value {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
NSString* prefixedKey;
|
||||
prefixedKey = [self addPrefix:key];
|
||||
[prefs setObject:value forKey:prefixedKey];
|
||||
}
|
||||
|
||||
- (NSString*) getString:(NSString *)key {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
return [prefs stringForKey:key];
|
||||
}
|
||||
|
||||
// All the following must convert their type to NSNumber for JavaScript.
|
||||
|
||||
// Integer
|
||||
|
||||
- (void) setInteger:(NSString*)key withValue:(NSString*)value {
|
||||
NSString* prefixedKey;
|
||||
prefixedKey = [self addPrefix:key];
|
||||
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
NSInteger myInt = [value intValue];
|
||||
[prefs setInteger:myInt forKey:prefixedKey];
|
||||
}
|
||||
|
||||
- (NSNumber*) getInteger:(NSString *)key {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
return [NSNumber numberWithInteger:[prefs integerForKey:key]];
|
||||
}
|
||||
|
||||
// Boolean
|
||||
|
||||
- (void) setBool:(NSString*)key withValue:(NSString*)value {
|
||||
NSString* prefixedKey;
|
||||
prefixedKey = [self addPrefix:key];
|
||||
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
BOOL myBool = [value boolValue];
|
||||
[prefs setBool:myBool forKey:prefixedKey];
|
||||
}
|
||||
|
||||
- (NSNumber*) getBool:(NSString *)key {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
return [NSNumber numberWithBool:[prefs boolForKey:key]];
|
||||
}
|
||||
|
||||
// Float
|
||||
|
||||
- (void) setFloat:(NSString*)key withValue:(NSString*)value {
|
||||
NSString* prefixedKey;
|
||||
prefixedKey = [self addPrefix:key];
|
||||
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
float myFloat = [value floatValue];
|
||||
[prefs setFloat:myFloat forKey:prefixedKey];
|
||||
}
|
||||
|
||||
- (NSNumber*) getFloat:(NSString *)key {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
return [NSNumber numberWithFloat:[prefs floatForKey:key]];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark WebScripting Protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector {
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector {
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(getMyDefaults)) {
|
||||
result = @"getMyDefaults";
|
||||
}
|
||||
|
||||
if (selector == @selector(removeObjectForKey:)) {
|
||||
result = @"removeObjectForKey";
|
||||
}
|
||||
|
||||
else if (selector == @selector(setString:withValue:)) {
|
||||
result = @"setString";
|
||||
} else if (selector == @selector(getString:)) {
|
||||
result = @"getString";
|
||||
}
|
||||
|
||||
else if (selector == @selector(setInteger:withValue:)) {
|
||||
result = @"setInteger";
|
||||
} else if (selector == @selector(getInteger:)) {
|
||||
result = @"getInteger";
|
||||
}
|
||||
|
||||
else if (selector == @selector(setBool:withValue:)) {
|
||||
result = @"setBool";
|
||||
} else if (selector == @selector(getBool:)) {
|
||||
result = @"getBool";
|
||||
}
|
||||
|
||||
else if (selector == @selector(setFloat:withValue:)) {
|
||||
result = @"setFloat";
|
||||
} else if (selector == @selector(getFloat:)) {
|
||||
result = @"getFloat";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name {
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,9 @@
|
|||
@interface Fonts : NSObject {
|
||||
}
|
||||
|
||||
- (NSArray*) availableFonts;
|
||||
- (NSArray*) availableFontFamilies;
|
||||
- (NSArray*) availableMembersOfFontFamily:(NSString*)fontFamily;
|
||||
- (CGFloat) defaultLineHeightForFont:(NSString *)theFontName ofSize:(CGFloat)theFontSize;
|
||||
|
||||
@end
|
|
@ -0,0 +1,48 @@
|
|||
#import "fonts.h"
|
||||
|
||||
@implementation Fonts
|
||||
|
||||
|
||||
- (NSArray*) availableFonts {
|
||||
return [[NSFontManager sharedFontManager] availableFonts];
|
||||
}
|
||||
|
||||
- (NSArray*) availableFontFamilies {
|
||||
return [[NSFontManager sharedFontManager] availableFontFamilies];
|
||||
}
|
||||
|
||||
- (NSArray*) availableMembersOfFontFamily:(NSString *)fontFamily {
|
||||
return [[NSFontManager sharedFontManager] availableMembersOfFontFamily:fontFamily];
|
||||
}
|
||||
|
||||
- (CGFloat) defaultLineHeightForFont:(NSString*)theFontName ofSize:(CGFloat)theFontSize {
|
||||
NSFont *theFont = [NSFont fontWithName:theFontName size:theFontSize];
|
||||
NSLayoutManager *lm = [[NSLayoutManager alloc] init];
|
||||
|
||||
return [lm defaultLineHeightForFont:theFont];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark WebScripting Protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector {
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector {
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(availableMembersOfFontFamily:)) {
|
||||
result = @"availableMembersOfFontFamily";
|
||||
} else if (selector == @selector(defaultLineHeightForFont:ofSize:)) {
|
||||
result = @"defaultLineHeightForFont";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name {
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,7 @@
|
|||
// Application constants
|
||||
|
||||
#define kStartPage @"http://127.0.0.1:9993/"
|
||||
|
||||
#define kStartFolder @"."
|
||||
|
||||
#define kWebScriptNamespace @"macgap"
|
|
@ -0,0 +1,15 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
@class WebViewDelegate;
|
||||
|
||||
@interface ContentView : NSView {
|
||||
IBOutlet WebView* webView;
|
||||
WebViewDelegate* delegate;
|
||||
}
|
||||
|
||||
@property (retain) WebView* webView;
|
||||
@property (retain) WebViewDelegate* delegate;
|
||||
@property (strong) IBOutlet NSMenu *mainMenu;
|
||||
|
||||
@end
|
|
@ -0,0 +1,68 @@
|
|||
#import "ContentView.h"
|
||||
#import "WebViewDelegate.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "JSEventHelper.h"
|
||||
|
||||
@interface WebPreferences (WebPreferencesPrivate)
|
||||
- (void)_setLocalStorageDatabasePath:(NSString *)path;
|
||||
- (void) setLocalStorageEnabled: (BOOL) localStorageEnabled;
|
||||
- (void) setDatabasesEnabled:(BOOL)databasesEnabled;
|
||||
- (void) setDeveloperExtrasEnabled:(BOOL)developerExtrasEnabled;
|
||||
- (void) setWebGLEnabled:(BOOL)webGLEnabled;
|
||||
- (void) setOfflineWebApplicationCacheEnabled:(BOOL)offlineWebApplicationCacheEnabled;
|
||||
@end
|
||||
|
||||
@implementation ContentView
|
||||
|
||||
@synthesize webView, delegate, mainMenu;
|
||||
|
||||
- (void) awakeFromNib
|
||||
{
|
||||
WebPreferences *webPrefs = [WebPreferences standardPreferences];
|
||||
|
||||
NSString *cappBundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
|
||||
NSString *applicationSupportFile = [@"~/Library/Application Support/" stringByExpandingTildeInPath];
|
||||
NSString *savePath = [NSString pathWithComponents:[NSArray arrayWithObjects:applicationSupportFile, cappBundleName, @"LocalStorage", nil]];
|
||||
[webPrefs _setLocalStorageDatabasePath:savePath];
|
||||
[webPrefs setLocalStorageEnabled:YES];
|
||||
[webPrefs setDatabasesEnabled:YES];
|
||||
[webPrefs setDeveloperExtrasEnabled:[[NSUserDefaults standardUserDefaults] boolForKey: @"developer"]];
|
||||
[webPrefs setOfflineWebApplicationCacheEnabled:YES];
|
||||
[webPrefs setWebGLEnabled:YES];
|
||||
|
||||
[self.webView setPreferences:webPrefs];
|
||||
|
||||
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage
|
||||
sharedHTTPCookieStorage];
|
||||
[cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
|
||||
|
||||
[self.webView setApplicationNameForUserAgent: @"MacGap"];
|
||||
|
||||
self.delegate = [[WebViewDelegate alloc] initWithMenu:[NSApp mainMenu]];
|
||||
// [self.webView setFrameLoadDelegate:self.delegate];
|
||||
// [self.webView setUIDelegate:self.delegate];
|
||||
// [self.webView setResourceLoadDelegate:self.delegate];
|
||||
// [self.webView setDownloadDelegate:self.delegate];
|
||||
// [self.webView setPolicyDelegate:self.delegate];
|
||||
[self.webView setDrawsBackground:NO];
|
||||
[self.webView setShouldCloseWithWindow:NO];
|
||||
|
||||
[self.webView setGroupName:@"MacGap"];
|
||||
|
||||
}
|
||||
|
||||
- (void) windowResized:(NSNotification*)notification;
|
||||
{
|
||||
NSWindow* window = (NSWindow*)notification.object;
|
||||
NSSize size = [window frame].size;
|
||||
|
||||
DebugNSLog(@"window width = %f, window height = %f", size.width, size.height);
|
||||
|
||||
bool isFullScreen = (window.styleMask & NSFullScreenWindowMask) == NSFullScreenWindowMask;
|
||||
int titleBarHeight = isFullScreen ? 0 : [[Utils sharedInstance] titleBarHeight:window];
|
||||
|
||||
[self.webView setFrame:NSMakeRect(0, 0, size.width, size.height - titleBarHeight)];
|
||||
[JSEventHelper triggerEvent:@"orientationchange" forWebView:self.webView];
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// Helper.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Liam Kaufman Simpkins on 12-01-22.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "WindowController.h"
|
||||
|
||||
@interface JSEventHelper : NSObject
|
||||
|
||||
+ (void) triggerEvent:(NSString *)event forWebView:(WebView *)webView;
|
||||
+ (void) triggerEvent:(NSString *)event withArgs:(NSDictionary *)args forWebView:(WebView *)webView;
|
||||
+ (void) triggerEvent:(NSString *)event withArgs:(NSDictionary *)args forObject:(NSString *)objName forWebView:(WebView *)webView;
|
||||
+ (void) triggerEvent:(NSString *)event forDetail:(NSString *)detail forWebView:(WebView *)webView;
|
||||
+ (void) triggerEvent:(NSString *)event forDetail:(NSString *)detail forObject:(NSString *)objName forWebView:(WebView *)webView;
|
||||
|
||||
@end
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// Helper.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Liam Kaufman Simpkins on 12-01-22.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JSEventHelper.h"
|
||||
|
||||
@implementation JSEventHelper
|
||||
|
||||
+ (void) triggerEvent:(NSString *)event forWebView:(WebView *)webView {
|
||||
[self triggerEvent:event withArgs:[NSMutableDictionary dictionary] forObject:@"document" forWebView:webView];
|
||||
}
|
||||
|
||||
+ (void) triggerEvent:(NSString *)event withArgs:(NSDictionary *)args forWebView:(WebView *)webView {
|
||||
[self triggerEvent:event withArgs:args forObject:@"document" forWebView:webView];
|
||||
}
|
||||
|
||||
+ (void) triggerEvent:(NSString *)event withArgs:(NSDictionary *)args forObject:(NSString *)objName forWebView:(WebView *)webView {
|
||||
|
||||
// Convert args Dictionary to JSON.
|
||||
NSString* jsonString = [[Utils sharedInstance] convertDictionaryToJSON:args];
|
||||
|
||||
// Create the event JavaScript and run it.
|
||||
NSString * str = [NSString stringWithFormat:@"var e = document.createEvent('Events'); e.initEvent('%@', true, false); e.data=%@; %@.dispatchEvent(e); ", event, jsonString, objName];
|
||||
[webView stringByEvaluatingJavaScriptFromString:str];
|
||||
}
|
||||
|
||||
+ (void) triggerEvent:(NSString *)event forDetail:(NSString *)detail forWebView:(WebView *)webView {
|
||||
[self triggerEvent:event forDetail:detail forObject:@"document" forWebView:webView];
|
||||
}
|
||||
|
||||
+ (void) triggerEvent:(NSString *)event forDetail:(NSString *)detail forObject:(NSString *)objName forWebView:(WebView *)webView {
|
||||
NSString *detailEscaped = [detail stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
|
||||
NSString *str = [NSString stringWithFormat:@"var e = new CustomEvent('%@', { 'detail': decodeURIComponent(\"%@\") }); %@.dispatchEvent(e); ", event, detailEscaped, objName];
|
||||
[webView stringByEvaluatingJavaScriptFromString:str];
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,20 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import <Webkit/WebScriptObject.h>
|
||||
|
||||
#define DEG_EPS 0.001
|
||||
#define fequal(a,b) (fabs((a) - (b)) < DEG_EPS)
|
||||
#define fequalzero(a) (fabs(a) < DEG_EPS)
|
||||
|
||||
@class LoadingView;
|
||||
|
||||
@interface Utils : NSObject {
|
||||
}
|
||||
|
||||
- (float) titleBarHeight:(NSWindow*)aWindow;
|
||||
- (NSString*) pathForResource:(NSString*)resourcepath;
|
||||
- (NSString*) convertDictionaryToJSON:(NSDictionary*)dict;
|
||||
- (NSArray*) convertJSarrayToNSArray:(WebScriptObject*)jsArray;
|
||||
|
||||
+ (Utils*) sharedInstance;
|
||||
|
||||
@end
|
|
@ -0,0 +1,93 @@
|
|||
#import "Utils.h"
|
||||
#import <Webkit/WebScriptObject.h>
|
||||
|
||||
static Utils* sharedInstance = nil;
|
||||
|
||||
@implementation Utils
|
||||
|
||||
- (float) titleBarHeight:(NSWindow*)aWindow
|
||||
{
|
||||
NSRect frame = [aWindow frame];
|
||||
NSRect contentRect = [NSWindow contentRectForFrameRect: frame
|
||||
styleMask: NSTitledWindowMask];
|
||||
|
||||
return (frame.size.height - contentRect.size.height);
|
||||
}
|
||||
|
||||
- (NSString*) pathForResource:(NSString*)resourcepath
|
||||
{
|
||||
NSBundle * mainBundle = [NSBundle mainBundle];
|
||||
NSMutableArray *directoryParts = [NSMutableArray arrayWithArray:[resourcepath componentsSeparatedByString:@"/"]];
|
||||
NSString *filename = [directoryParts lastObject];
|
||||
[directoryParts removeLastObject];
|
||||
|
||||
NSString *directoryStr = [NSString stringWithFormat:@"%@/%@", kStartFolder, [directoryParts componentsJoinedByString:@"/"]];
|
||||
return [mainBundle pathForResource:filename
|
||||
ofType:@""
|
||||
inDirectory:directoryStr];
|
||||
}
|
||||
|
||||
- (NSString*) convertDictionaryToJSON:(NSDictionary*)dict {
|
||||
// Convert defaults Dictionary to JSON.
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization
|
||||
dataWithJSONObject:dict
|
||||
options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
|
||||
error:&error];
|
||||
|
||||
NSString *jsonString;
|
||||
if (! jsonData) {
|
||||
NSLog(@"Got an error converting to JSON: %@", error);
|
||||
}
|
||||
else {
|
||||
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
return jsonString;
|
||||
}
|
||||
|
||||
// Convert JavaScript array (arrives as a WebScriptObject) into an NSArray of strings.
|
||||
- (NSArray*) convertJSarrayToNSArray:(WebScriptObject*)jsArray {
|
||||
NSInteger count = [[jsArray valueForKey:@"length"] integerValue];
|
||||
|
||||
NSMutableArray *args = [NSMutableArray array];
|
||||
for (int i = 0; i < count; i++) {
|
||||
NSString *item = [jsArray webScriptValueAtIndex:i];
|
||||
if ([item isKindOfClass:[NSString class]]) {
|
||||
[args addObject:item];
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Singleton methods
|
||||
|
||||
+ (Utils*) sharedInstance
|
||||
{
|
||||
@synchronized(self)
|
||||
{
|
||||
if (sharedInstance == nil){
|
||||
sharedInstance = [[Utils alloc] init];
|
||||
}
|
||||
}
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
+ (id) allocWithZone:(NSZone *)zone {
|
||||
@synchronized(self) {
|
||||
if (sharedInstance == nil) {
|
||||
sharedInstance = [super allocWithZone:zone];
|
||||
return sharedInstance; // assignment and return on first allocation
|
||||
}
|
||||
}
|
||||
return nil; // on subsequent allocation attempts return nil
|
||||
}
|
||||
|
||||
- (id) copyWithZone:(NSZone *)zone
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,49 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
@class Sound;
|
||||
@class Dock;
|
||||
@class Growl;
|
||||
@class Notice;
|
||||
@class Path;
|
||||
@class App;
|
||||
@class Window;
|
||||
@class Clipboard;
|
||||
@class Fonts;
|
||||
@class MenuProxy;
|
||||
@class UserDefaults;
|
||||
|
||||
@class WindowController;
|
||||
|
||||
@interface WebViewDelegate : NSObject {
|
||||
Sound* sound;
|
||||
Dock* dock;
|
||||
Growl* growl;
|
||||
Notice* notice;
|
||||
Path* path;
|
||||
App* app;
|
||||
Window* window;
|
||||
Clipboard* clipboard;
|
||||
Fonts* fonts;
|
||||
NSMenu *mainMenu;
|
||||
UserDefaults* userDefaults;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@property (nonatomic, retain) Sound* sound;
|
||||
@property (nonatomic, retain) Dock* dock;
|
||||
@property (nonatomic, retain) Growl* growl;
|
||||
@property (nonatomic, retain) Notice* notice;
|
||||
@property (nonatomic, retain) Path* path;
|
||||
@property (nonatomic, retain) App* app;
|
||||
@property (nonatomic, retain) Window* window;
|
||||
@property (nonatomic, retain) Clipboard* clipboard;
|
||||
@property (nonatomic, retain) Fonts* fonts;
|
||||
@property (nonatomic, retain) MenuProxy* menu;
|
||||
@property (nonatomic, retain) UserDefaults* userDefaults;
|
||||
|
||||
@property (nonatomic, retain) WindowController *requestedWindow;
|
||||
|
||||
- (id) initWithMenu:(NSMenu*)menu;
|
||||
@end
|
|
@ -0,0 +1,206 @@
|
|||
#import "WebViewDelegate.h"
|
||||
#import "Sound.h"
|
||||
#import "Dock.h"
|
||||
#import "Notice.h"
|
||||
#import "Path.h"
|
||||
#import "App.h"
|
||||
#import "Window.h"
|
||||
#import "WindowController.h"
|
||||
#import "Clipboard.h"
|
||||
#import "Fonts.h"
|
||||
#import "MenuProxy.h"
|
||||
#import "UserDefaults.h"
|
||||
|
||||
@implementation WebViewDelegate
|
||||
|
||||
@synthesize sound;
|
||||
@synthesize dock;
|
||||
@synthesize growl;
|
||||
@synthesize notice;
|
||||
@synthesize path;
|
||||
@synthesize app;
|
||||
@synthesize window;
|
||||
@synthesize requestedWindow;
|
||||
@synthesize clipboard;
|
||||
@synthesize fonts;
|
||||
@synthesize menu;
|
||||
@synthesize userDefaults;
|
||||
|
||||
- (id) initWithMenu:(NSMenu*)aMenu
|
||||
{
|
||||
self = [super init];
|
||||
if (!self)
|
||||
return nil;
|
||||
|
||||
mainMenu = aMenu;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) webView:(WebView*)webView didClearWindowObject:(WebScriptObject*)windowScriptObject forFrame:(WebFrame *)frame
|
||||
{
|
||||
JSContextRef context = [frame globalContext];
|
||||
if (self.sound == nil) { self.sound = [[Sound alloc] initWithContext:context]; }
|
||||
if (self.dock == nil) { self.dock = [Dock new]; }
|
||||
if (self.path == nil) { self.path = [Path new]; }
|
||||
if (self.clipboard == nil) { self.clipboard = [Clipboard new]; }
|
||||
if (self.fonts == nil) { self.fonts = [Fonts new]; }
|
||||
|
||||
if (self.notice == nil && [Notice available] == YES) {
|
||||
self.notice = [[Notice alloc] initWithWebView:webView];
|
||||
}
|
||||
|
||||
if (self.app == nil) {
|
||||
self.app = [[App alloc] initWithWebView:webView];
|
||||
}
|
||||
|
||||
if (self.window == nil) {
|
||||
self.window = [[Window alloc] initWithWebView:webView];
|
||||
}
|
||||
|
||||
if (self.menu == nil) {
|
||||
self.menu = [MenuProxy proxyWithContext:context andMenu:mainMenu];
|
||||
}
|
||||
|
||||
if (self.userDefaults == nil) {
|
||||
self.userDefaults = [[UserDefaults alloc] initWithWebView:webView];
|
||||
}
|
||||
|
||||
[windowScriptObject setValue:self forKey:kWebScriptNamespace];
|
||||
}
|
||||
|
||||
|
||||
- (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id < WebOpenPanelResultListener >)resultListener allowMultipleFiles:(BOOL)allowMultipleFiles{
|
||||
|
||||
NSOpenPanel * openDlg = [NSOpenPanel openPanel];
|
||||
|
||||
[openDlg setCanChooseFiles:YES];
|
||||
[openDlg setCanChooseDirectories:NO];
|
||||
|
||||
[openDlg beginWithCompletionHandler:^(NSInteger result){
|
||||
if (result == NSFileHandlingPanelOKButton) {
|
||||
NSArray * files = [[openDlg URLs] valueForKey: @"relativePath"];
|
||||
[resultListener chooseFilenames: files];
|
||||
} else {
|
||||
[resultListener cancel];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) webView:(WebView*)webView addMessageToConsole:(NSDictionary*)message
|
||||
{
|
||||
if (![message isKindOfClass:[NSDictionary class]]) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"JavaScript console: %@:%@: %@",
|
||||
[[message objectForKey:@"sourceURL"] lastPathComponent], // could be nil
|
||||
[message objectForKey:@"lineNumber"],
|
||||
[message objectForKey:@"message"]);
|
||||
}
|
||||
|
||||
- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
|
||||
{
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert addButtonWithTitle:@"OK"];
|
||||
[alert setMessageText:message];
|
||||
[alert setAlertStyle:NSWarningAlertStyle];
|
||||
[alert runModal];
|
||||
}
|
||||
|
||||
- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
|
||||
{
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert addButtonWithTitle:@"Yes"];
|
||||
[alert addButtonWithTitle:@"No"];
|
||||
[alert setMessageText:message];
|
||||
[alert setAlertStyle:NSWarningAlertStyle];
|
||||
|
||||
if ([alert runModal] == NSAlertFirstButtonReturn)
|
||||
return YES;
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*
|
||||
By default the size of a database is set to 0 [1]. When a database is being created
|
||||
it calls this delegate method to get an increase in quota size - or call an error.
|
||||
PS this method is defined in WebUIDelegatePrivate and may make it difficult, but
|
||||
not impossible [2], to get an app accepted into the mac app store.
|
||||
|
||||
Further reading:
|
||||
[1] http://stackoverflow.com/questions/353808/implementing-a-webview-database-quota-delegate
|
||||
[2] http://stackoverflow.com/questions/4527905/how-do-i-enable-local-storage-in-my-webkit-based-application/4608549#4608549
|
||||
*/
|
||||
- (void)webView:(WebView *)sender frame:(WebFrame *)frame exceededDatabaseQuotaForSecurityOrigin:(id) origin database:(NSString *)databaseIdentifier
|
||||
{
|
||||
static const unsigned long long defaultQuota = 5 * 1024 * 1024;
|
||||
if ([origin respondsToSelector: @selector(setQuota:)]) {
|
||||
[origin performSelector:@selector(setQuota:) withObject:[NSNumber numberWithLongLong: defaultQuota]];
|
||||
} else {
|
||||
NSLog(@"could not increase quota for %lld", defaultQuota);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems
|
||||
{
|
||||
NSMutableArray *webViewMenuItems = [defaultMenuItems mutableCopy];
|
||||
|
||||
if (webViewMenuItems)
|
||||
{
|
||||
NSEnumerator *itemEnumerator = [defaultMenuItems objectEnumerator];
|
||||
NSMenuItem *menuItem = nil;
|
||||
while ((menuItem = [itemEnumerator nextObject]))
|
||||
{
|
||||
NSInteger tag = [menuItem tag];
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case WebMenuItemTagOpenLinkInNewWindow:
|
||||
case WebMenuItemTagDownloadLinkToDisk:
|
||||
case WebMenuItemTagCopyLinkToClipboard:
|
||||
case WebMenuItemTagOpenImageInNewWindow:
|
||||
case WebMenuItemTagDownloadImageToDisk:
|
||||
case WebMenuItemTagCopyImageToClipboard:
|
||||
case WebMenuItemTagOpenFrameInNewWindow:
|
||||
case WebMenuItemTagGoBack:
|
||||
case WebMenuItemTagGoForward:
|
||||
case WebMenuItemTagStop:
|
||||
case WebMenuItemTagOpenWithDefaultApplication:
|
||||
case WebMenuItemTagReload:
|
||||
[webViewMenuItems removeObjectIdenticalTo: menuItem];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return webViewMenuItems;
|
||||
}
|
||||
|
||||
- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request{
|
||||
requestedWindow = [[WindowController alloc] initWithRequest:request];
|
||||
return requestedWindow.contentView.webView;
|
||||
}
|
||||
|
||||
- (void)webViewShow:(WebView *)sender{
|
||||
[requestedWindow showWindow:sender];
|
||||
}
|
||||
|
||||
- (void)webView:(WebView *)webView decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id < WebPolicyDecisionListener >)listener
|
||||
{
|
||||
[[NSWorkspace sharedWorkspace] openURL:[request URL]];
|
||||
[listener ignore];
|
||||
}
|
||||
|
||||
#pragma mark WebScripting protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -0,0 +1,23 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "WindowController.h"
|
||||
|
||||
@interface Window : NSObject{
|
||||
CGRect _oldRestoreFrame;
|
||||
}
|
||||
|
||||
@property (retain, nonatomic) WindowController *windowController;
|
||||
@property (nonatomic, retain) WebView *webView;
|
||||
|
||||
- (id) initWithWebView:(WebView *)view;
|
||||
- (void) open:(NSDictionary *)properties;
|
||||
- (void) move:(NSDictionary *)properties;
|
||||
- (void) resize:(NSDictionary *) properties;
|
||||
- (Boolean) isMaximized;
|
||||
- (CGFloat) getX;
|
||||
- (CGFloat) getY;
|
||||
- (void) maximize;
|
||||
- (void) restore;
|
||||
- (void) toggleFullscreen;
|
||||
|
||||
@end
|
|
@ -0,0 +1,94 @@
|
|||
#import "Window.h"
|
||||
|
||||
@implementation Window
|
||||
|
||||
@synthesize windowController, webView;
|
||||
|
||||
- (id) initWithWebView:(WebView*)view
|
||||
{
|
||||
if(self = [super init]) {
|
||||
self.webView = view;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) open:(NSDictionary *)properties
|
||||
{
|
||||
self.windowController = [[WindowController alloc] initWithURL:[properties valueForKey:@"url"]];
|
||||
[self.windowController showWindow: [NSApplication sharedApplication].delegate];
|
||||
[self.windowController.window makeKeyWindow];
|
||||
}
|
||||
|
||||
- (void) minimize {
|
||||
[[NSApp mainWindow] miniaturize:[NSApp mainWindow]];
|
||||
}
|
||||
|
||||
- (void) toggleFullscreen {
|
||||
[[NSApp mainWindow] toggleFullScreen:[NSApp mainWindow]];
|
||||
}
|
||||
|
||||
- (void) maximize {
|
||||
CGRect a = [NSApp mainWindow].frame;
|
||||
_oldRestoreFrame = CGRectMake(a.origin.x, a.origin.y, a.size.width, a.size.height);
|
||||
[[NSApp mainWindow] setFrame:[[NSScreen mainScreen] visibleFrame] display:YES];
|
||||
}
|
||||
|
||||
- (Boolean) isMaximized {
|
||||
NSRect a = [NSApp mainWindow].frame;
|
||||
NSRect b = [[NSScreen mainScreen] visibleFrame];
|
||||
return a.origin.x == b.origin.x && a.origin.y == b.origin.y && a.size.width == b.size.width && a.size.height == b.size.height;
|
||||
}
|
||||
|
||||
- (CGFloat) getX {
|
||||
NSRect frame = [self.webView window].frame;
|
||||
return frame.origin.x;
|
||||
}
|
||||
|
||||
- (CGFloat) getY {
|
||||
NSRect frame = [self.webView window].frame;
|
||||
return frame.origin.y;
|
||||
}
|
||||
|
||||
- (void) move:(NSDictionary *)properties
|
||||
{
|
||||
NSRect frame = [self.webView window].frame;
|
||||
frame.origin.x = [[properties valueForKey:@"x"] doubleValue];
|
||||
frame.origin.y = [[properties valueForKey:@"y"] doubleValue];
|
||||
[[self.webView window] setFrame:frame display:YES];
|
||||
|
||||
}
|
||||
|
||||
- (void) resize:(NSDictionary *) properties
|
||||
{
|
||||
NSRect frame = [self.webView window].frame;
|
||||
frame.size.width = [[properties valueForKey:@"width"] doubleValue];
|
||||
frame.size.height = [[properties valueForKey:@"height"] doubleValue];
|
||||
[[self.webView window] setFrame:frame display:YES];
|
||||
}
|
||||
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector{
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(open:)) {
|
||||
result = @"open";
|
||||
}else if (selector == @selector(move:)){
|
||||
result = @"move";
|
||||
}else if (selector == @selector(resize:)){
|
||||
result = @"resize";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,10 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Clipboard : NSObject {
|
||||
|
||||
}
|
||||
|
||||
- (void) copy:(NSString*)text;
|
||||
- (NSString *) paste;
|
||||
|
||||
@end
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// clipboard.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by David Zorychta on 2013-07-22.
|
||||
// Copyright (c) 2013 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Clipboard.h"
|
||||
|
||||
@implementation Clipboard
|
||||
|
||||
- (void) copy:(NSString*)text {
|
||||
[[NSPasteboard generalPasteboard] clearContents];
|
||||
[[NSPasteboard generalPasteboard] setString:text forType:NSStringPboardType];
|
||||
}
|
||||
|
||||
- (NSString *) paste {
|
||||
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
|
||||
NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
|
||||
NSDictionary *options = [NSDictionary dictionary];
|
||||
BOOL ok = [pasteboard canReadObjectForClasses:classArray options:options];
|
||||
if (ok) {
|
||||
NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options];
|
||||
return (NSString *) [objectsToPaste objectAtIndex:0];
|
||||
}
|
||||
return @"";
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector
|
||||
{
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(copy:)) {
|
||||
result = @"copy";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>ZeroTier One</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>ZeroTierIcon</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>ZeroTier One</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// Prefix header for all source files of the 'MacGap' target in the 'MacGap' project
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#ifdef _DEBUG
|
||||
#define DebugNSLog(format, ...) NSLog(format, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DebugNSLog(format, ...)
|
||||
#endif
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "Constants.h"
|
||||
#import "Utils.h"
|
||||
#endif
|
|
@ -0,0 +1,13 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
#import "ContentView.h"
|
||||
|
||||
@interface WindowController : NSWindowController {
|
||||
|
||||
}
|
||||
|
||||
- (id) initWithURL:(NSString *) url;
|
||||
- (id) initWithRequest: (NSURLRequest *)request;
|
||||
@property (retain) NSURL * url;
|
||||
@property (retain) IBOutlet ContentView *contentView;
|
||||
|
||||
@end
|
|
@ -0,0 +1,54 @@
|
|||
#import "WindowController.h"
|
||||
|
||||
|
||||
@interface WindowController() {
|
||||
|
||||
}
|
||||
|
||||
-(void) notificationCenter;
|
||||
|
||||
@end
|
||||
|
||||
@implementation WindowController
|
||||
|
||||
@synthesize contentView, url;
|
||||
|
||||
- (id) initWithURL:(NSString *) relativeURL{
|
||||
self = [super initWithWindowNibName:@"Window"];
|
||||
self.url = [NSURL URLWithString:relativeURL relativeToURL:[[NSBundle mainBundle] resourceURL]];
|
||||
|
||||
[self.window setFrameAutosaveName:@"MacGapWindow"];
|
||||
[self notificationCenter];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id) initWithRequest: (NSURLRequest *)request{
|
||||
self = [super initWithWindowNibName:@"Window"];
|
||||
[self notificationCenter];
|
||||
[[self.contentView.webView mainFrame] loadRequest:request];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) notificationCenter{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self.contentView
|
||||
selector:@selector(windowResized:)
|
||||
name:NSWindowDidResizeNotification
|
||||
object:[self window]];
|
||||
}
|
||||
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
[super windowDidLoad];
|
||||
|
||||
if (self.url != nil) {
|
||||
[self.contentView.webView setMainFrameURL:[self.url absoluteString]];
|
||||
}
|
||||
|
||||
|
||||
// Implement this method to handle any initialization after your
|
||||
// window controller's window has been loaded from its nib file.
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,13 @@
|
|||
{\rtf1\ansi\ansicpg1252\cocoartf1347\cocoasubrtf570
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\vieww9600\viewh8400\viewkind0
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
|
||||
|
||||
\f0\b\fs24 \cf0 (c)2011-2015 ZeroTier, Inc.\
|
||||
Licensed under the GNU GPLv3\
|
||||
\
|
||||
UI Wrapper MacGap (c) Twitter, Inc.\
|
||||
Licensed under the MIT License\
|
||||
http://macgap.com/\
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
/* Localized versions of Info.plist keys */
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9060"/>
|
||||
<plugIn identifier="com.apple.WebKitIBPlugin" version="9060"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="WindowController">
|
||||
<connections>
|
||||
<outlet property="contentView" destination="2" id="23"/>
|
||||
<outlet property="window" destination="1" id="25"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" animationBehavior="default" id="1">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<rect key="contentRect" x="575" y="564" width="500" height="500"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1178"/>
|
||||
<view key="contentView" id="2" customClass="ContentView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="500" height="500"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<webView id="5">
|
||||
<rect key="frame" x="0.0" y="0.0" width="500" height="500"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<animations/>
|
||||
<webPreferences key="preferences" defaultFontSize="12" defaultFixedFontSize="12">
|
||||
<nil key="identifier"/>
|
||||
</webPreferences>
|
||||
</webView>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<connections>
|
||||
<outlet property="webView" destination="5" id="19"/>
|
||||
</connections>
|
||||
</view>
|
||||
<connections>
|
||||
<binding destination="-2" name="title" keyPath="contentView.webView.mainFrameTitle" id="31"/>
|
||||
</connections>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// main.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Alex MacCaw on 08/01/2012.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
return NSApplicationMain(argc, (const char **)argv);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
Mac Web UI Wrapper
|
||||
======
|
||||
|
||||
This is a modified version of MacGap1 which launches a WebKit view and accesses the local ZeroTier service at its web URL. It builds the URL from the authtoken.secret file in the system home (or the user home) and the zerotier-one.port file that ZeroTier creates to advertise its control port.
|
||||
|
||||
It's based on the original MacGap1 source by Twitter, Inc. which is licensed under the MIT license.
|
46
ext/installfiles/mac/postinst.sh
Executable file
46
ext/installfiles/mac/postinst.sh
Executable file
|
@ -0,0 +1,46 @@
|
|||
#!/bin/bash
|
||||
|
||||
export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin
|
||||
|
||||
OSX_RELEASE=`sw_vers -productVersion | cut -d . -f 1,2`
|
||||
|
||||
launchctl unload /Library/LaunchDaemons/com.zerotier.one.plist >>/dev/null 2>&1
|
||||
sleep 1
|
||||
|
||||
cd "/Library/Application Support/ZeroTier/One"
|
||||
|
||||
if [ "$OSX_RELEASE" = "10.7" ]; then
|
||||
# OSX 10.7 cannot use the new tap driver since the new way of kext signing
|
||||
# is not backward compatible. Pull the old one for 10.7 users and replace.
|
||||
# We use https to fetch and check hash as an extra added measure.
|
||||
rm -f tap.kext.10_7.tar.gz
|
||||
curl -s https://download.zerotier.com/tap.kext.10_7.tar.gz >tap.kext.10_7.tar.gz
|
||||
if [ -s tap.kext.10_7.tar.gz -a "`shasum -a 256 tap.kext.10_7.tar.gz | cut -d ' ' -f 1`" = "e133d4832cef571621d3618f417381b44f51a76ed625089fb4e545e65d3ef2a9" ]; then
|
||||
rm -rf tap.kext
|
||||
tar -xzf tap.kext.10_7.tar.gz
|
||||
fi
|
||||
rm -f tap.kext.10_7.tar.gz
|
||||
fi
|
||||
|
||||
rm -rf node.log node.log.old root-topology shutdownIfUnreadable autoupdate.log updates.d
|
||||
chown -R 0 tap.kext
|
||||
chgrp -R 0 tap.kext
|
||||
if [ ! -f authtoken.secret ]; then
|
||||
head -c 4096 /dev/urandom | md5 | head -c 24 >authtoken.secret
|
||||
chown 0 authtoken.secret
|
||||
chgrp 0 authtoken.secret
|
||||
chmod 0600 authtoken.secret
|
||||
fi
|
||||
rm -f zerotier-cli zerotier-idtool
|
||||
ln -sf zerotier-one zerotier-cli
|
||||
ln -sf zerotier-one zerotier-idtool
|
||||
|
||||
mkdir -p /usr/local/bin
|
||||
cd /usr/local/bin
|
||||
rm -f zerotier-cli zerotier-idtool
|
||||
ln -sf "/Library/Application Support/ZeroTier/One/zerotier-one" zerotier-cli
|
||||
ln -sf "/Library/Application Support/ZeroTier/One/zerotier-one" zerotier-idtool
|
||||
|
||||
launchctl load /Library/LaunchDaemons/com.zerotier.one.plist >>/dev/null 2>&1
|
||||
|
||||
exit 0
|
26
ext/installfiles/mac/preinst.sh
Executable file
26
ext/installfiles/mac/preinst.sh
Executable file
|
@ -0,0 +1,26 @@
|
|||
#!/bin/bash
|
||||
|
||||
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
|
||||
|
||||
if [ -f /Library/LaunchDaemons/com.zerotier.one.plist ]; then
|
||||
launchctl unload /Library/LaunchDaemons/com.zerotier.one.plist >>/dev/null 2>&1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
|
||||
if [ -d "/Library/Application Support/ZeroTier/One" ]; then
|
||||
cd "/Library/Application Support/ZeroTier/One"
|
||||
if [ -f "zerotier-one.pid" ]; then
|
||||
ztpid=`cat zerotier-one.pid`
|
||||
if [ "$ztpid" -gt "0" ]; then
|
||||
kill `cat zerotier-one.pid`
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
|
||||
cd "/Applications"
|
||||
rm -rf "ZeroTier One.app"
|
||||
|
||||
exit 0
|
6
ext/installfiles/mac/ui/Makefile
Normal file
6
ext/installfiles/mac/ui/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
|||
all:
|
||||
mkdir -p build
|
||||
jsx --target es3 -x jsx . ./build
|
||||
rm -f ztui.min.js
|
||||
minify build/*.js >>ztui.min.js
|
||||
rm -rf build
|
10
ext/installfiles/mac/ui/README.md
Normal file
10
ext/installfiles/mac/ui/README.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
ZeroTier HTML5 UI
|
||||
======
|
||||
|
||||
This is the new (as of 1.0.3) ZeroTier One UI. It's implemented in HTML5 and React.
|
||||
|
||||
If you make changes to the .jsx files, type 'make'. You will need NodeJS, react-tools, and minify installed and available in your path.
|
||||
|
||||
For this to work, these files must be installed in the 'ui' subfolder of the ZeroTier home path. For development it's nice to symlink this to the 'ui' folder in your working directory. If the 'ui' subfolder is not present, the UI static files will not be served by the embedded web server.
|
||||
|
||||
Packaging for Mac and Windows is accomplished by way of the wrappers in ext/. For Mac this is done with a modified version of MacGap. Windows uses a custom project that embeds a web view.
|
74
ext/installfiles/mac/ui/ZeroTierNetwork.jsx
Normal file
74
ext/installfiles/mac/ui/ZeroTierNetwork.jsx
Normal file
|
@ -0,0 +1,74 @@
|
|||
var ZeroTierNetwork = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {};
|
||||
},
|
||||
|
||||
leaveNetwork: function(event) {
|
||||
Ajax.call({
|
||||
url: 'network/'+this.props.nwid+'?auth='+this.props.authToken,
|
||||
cache: false,
|
||||
type: 'DELETE',
|
||||
success: function(data) {
|
||||
if (this.props.onNetworkDeleted)
|
||||
this.props.onNetworkDeleted(this.props.nwid);
|
||||
}.bind(this),
|
||||
error: function(error) {
|
||||
}.bind(this)
|
||||
});
|
||||
event.preventDefault();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="zeroTierNetwork">
|
||||
<div className="networkInfo">
|
||||
<span className="networkId">{this.props.nwid}</span>
|
||||
<span className="networkName">{this.props.name}</span>
|
||||
</div>
|
||||
<div className="networkProps">
|
||||
<div className="row">
|
||||
<div className="name">Status</div>
|
||||
<div className="value">{this.props['status']}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">Type</div>
|
||||
<div className="value">{this.props['type']}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">MAC</div>
|
||||
<div className="value zeroTierAddress">{this.props['mac']}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">MTU</div>
|
||||
<div className="value">{this.props['mtu']}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">Broadcast</div>
|
||||
<div className="value">{(this.props['broadcastEnabled']) ? 'ENABLED' : 'DISABLED'}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">Bridging</div>
|
||||
<div className="value">{(this.props['bridge']) ? 'ACTIVE' : 'DISABLED'}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">Device</div>
|
||||
<div className="value">{(this.props['portDeviceName']) ? this.props['portDeviceName'] : '(none)'}</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="name">Managed IPs</div>
|
||||
<div className="value ipList">
|
||||
{
|
||||
this.props['assignedAddresses'].map(function(ipAssignment) {
|
||||
return (
|
||||
<div key={ipAssignment} className="ipAddress">{ipAssignment}</div>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" className="leaveNetworkButton" onClick={this.leaveNetwork}>Leave Network</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
158
ext/installfiles/mac/ui/ZeroTierNode.jsx
Normal file
158
ext/installfiles/mac/ui/ZeroTierNode.jsx
Normal file
|
@ -0,0 +1,158 @@
|
|||
var ZeroTierNode = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
address: '----------',
|
||||
online: false,
|
||||
version: '_._._',
|
||||
_networks: [],
|
||||
_peers: []
|
||||
};
|
||||
},
|
||||
|
||||
ago: function(ms) {
|
||||
if (ms > 0) {
|
||||
var tmp = Math.round((Date.now() - ms) / 1000);
|
||||
return ((tmp > 0) ? tmp : 0);
|
||||
} else return 0;
|
||||
},
|
||||
|
||||
updatePeers: function() {
|
||||
Ajax.call({
|
||||
url: 'peer?auth='+this.props.authToken,
|
||||
cache: false,
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
if (data) {
|
||||
var pl = JSON.parse(data);
|
||||
if (Array.isArray(pl)) {
|
||||
this.setState({_peers: pl});
|
||||
}
|
||||
}
|
||||
}.bind(this),
|
||||
error: function() {
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
updateNetworks: function() {
|
||||
Ajax.call({
|
||||
url: 'network?auth='+this.props.authToken,
|
||||
cache: false,
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
if (data) {
|
||||
var nwl = JSON.parse(data);
|
||||
if (Array.isArray(nwl)) {
|
||||
this.setState({_networks: nwl});
|
||||
}
|
||||
}
|
||||
}.bind(this),
|
||||
error: function() {
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
updateAll: function() {
|
||||
Ajax.call({
|
||||
url: 'status?auth='+this.props.authToken,
|
||||
cache: false,
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
this.alertedToFailure = false;
|
||||
if (data) {
|
||||
var status = JSON.parse(data);
|
||||
this.setState(status);
|
||||
document.title = 'ZeroTier One [' + status.address + ']';
|
||||
}
|
||||
this.updateNetworks();
|
||||
this.updatePeers();
|
||||
}.bind(this),
|
||||
error: function() {
|
||||
this.setState(this.getInitialState());
|
||||
if (!this.alertedToFailure) {
|
||||
this.alertedToFailure = true;
|
||||
alert('Authorization token invalid or ZeroTier One service not running.');
|
||||
}
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
joinNetwork: function(event) {
|
||||
event.preventDefault();
|
||||
if ((this.networkToJoin)&&(this.networkToJoin.length === 16)) {
|
||||
Ajax.call({
|
||||
url: 'network/'+this.networkToJoin+'?auth='+this.props.authToken,
|
||||
cache: false,
|
||||
type: 'POST',
|
||||
success: function(data) {
|
||||
this.networkToJoin = '';
|
||||
if (this.networkInputElement)
|
||||
this.networkInputElement.value = '';
|
||||
this.updateNetworks();
|
||||
}.bind(this),
|
||||
error: function() {
|
||||
}.bind(this)
|
||||
});
|
||||
} else {
|
||||
alert('To join a network, enter its 16-digit network ID.');
|
||||
}
|
||||
},
|
||||
handleNetworkIdEntry: function(event) {
|
||||
this.networkInputElement = event.target;
|
||||
var nid = this.networkInputElement.value;
|
||||
if (nid) {
|
||||
nid = nid.toLowerCase();
|
||||
var nnid = '';
|
||||
for(var i=0;((i<nid.length)&&(i<16));++i) {
|
||||
if ("0123456789abcdef".indexOf(nid.charAt(i)) >= 0)
|
||||
nnid += nid.charAt(i);
|
||||
}
|
||||
this.networkToJoin = nnid;
|
||||
this.networkInputElement.value = nnid;
|
||||
} else {
|
||||
this.networkToJoin = '';
|
||||
this.networkInputElement.value = '';
|
||||
}
|
||||
},
|
||||
|
||||
handleNetworkDelete: function(nwid) {
|
||||
var networks = [];
|
||||
for(var i=0;i<this.state._networks.length;++i) {
|
||||
if (this.state._networks[i].nwid !== nwid)
|
||||
networks.push(this.state._networks[i]);
|
||||
}
|
||||
this.setState({_networks: networks});
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.updateAll();
|
||||
this.updateIntervalId = setInterval(this.updateAll,2500);
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
clearInterval(this.updateIntervalId);
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<div className="zeroTierNode">
|
||||
<div className="middle"><div className="middleCell">
|
||||
<div className="middleScroll">
|
||||
<div className="networks" key="_networks">
|
||||
{
|
||||
this.state._networks.map(function(network) {
|
||||
network['authToken'] = this.props.authToken;
|
||||
network['onNetworkDeleted'] = this.handleNetworkDelete;
|
||||
return React.createElement('div',{className: 'network',key: network.nwid},React.createElement(ZeroTierNetwork,network));
|
||||
}.bind(this))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div className="bottom">
|
||||
<div className="left">
|
||||
<span className="statusLine"><span className="zeroTierAddress">{this.state.address}</span> {this.state.online ? (this.state.tcpFallbackActive ? 'TUNNELED' : 'ONLINE') : 'OFFLINE'} {this.state.version}</span>
|
||||
</div>
|
||||
<div className="right">
|
||||
<form onSubmit={this.joinNetwork}><input type="text" maxlength="16" placeholder="[ Network ID ]" onChange={this.handleNetworkIdEntry} size="16"/><button type="button" onClick={this.joinNetwork}>Join</button></form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue