mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-03-10 22:32:56 +00:00
Open sourcing the Breakpad framework from Google.
A=many, many people R=nealsid, jeremy moskovich(from Chromium project) git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@322 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
834
src/client/mac/sender/English.lproj/Breakpad.xib
Normal file
834
src/client/mac/sender/English.lproj/Breakpad.xib
Normal file
@@ -0,0 +1,834 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.02">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1050</int>
|
||||
<string key="IBDocument.SystemVersion">9F33</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">670</string>
|
||||
<string key="IBDocument.AppKitVersion">949.34</string>
|
||||
<string key="IBDocument.HIToolboxVersion">352.00</string>
|
||||
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<integer value="2"/>
|
||||
</object>
|
||||
<object class="NSArray" key="IBDocument.PluginDependencies">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSCustomObject" id="1001">
|
||||
<string key="NSClassName">Reporter</string>
|
||||
</object>
|
||||
<object class="NSCustomObject" id="1003">
|
||||
<string key="NSClassName">FirstResponder</string>
|
||||
</object>
|
||||
<object class="NSCustomObject" id="1004">
|
||||
<string key="NSClassName">NSApplication</string>
|
||||
</object>
|
||||
<object class="NSWindowTemplate" id="1005">
|
||||
<int key="NSWindowStyleMask">1</int>
|
||||
<int key="NSWindowBacking">2</int>
|
||||
<string key="NSWindowRect">{{196, 157}, {484, 353}}</string>
|
||||
<int key="NSWTFlags">536871936</int>
|
||||
<string key="NSWindowTitle"/>
|
||||
<string key="NSWindowClass">NSWindow</string>
|
||||
<nil key="NSViewClass"/>
|
||||
<string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
|
||||
<object class="NSView" key="NSWindowView" id="1006">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">264</int>
|
||||
<object class="NSMutableArray" key="NSSubviews">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSTextField" id="52942477">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">266</int>
|
||||
<string key="NSFrame">{{89, 279}, {378, 54}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSTextFieldCell" key="NSCell" id="237530958">
|
||||
<int key="NSCellFlags">67239424</int>
|
||||
<int key="NSCellFlags2">272629760</int>
|
||||
<string type="base64-UTF8" key="NSContents">RE8gTk9UIExPQ0FMSVpFLiBUaGUgPFJlYWxseSBMb25nIENvbXBhbnkgTmFtZT4gcHJvZ3JhbSA8UmVh
|
||||
bGx5IExvbmcgQXBwIE5hbWUgSGVyZT4gaGFzIHVuZXhwZWN0ZWRseSBxdWl0LiA</string>
|
||||
<object class="NSFont" key="NSSupport">
|
||||
<string key="NSName">LucidaGrande-Bold</string>
|
||||
<double key="NSSize">1.400000e+01</double>
|
||||
<int key="NSfFlags">16</int>
|
||||
</object>
|
||||
<reference key="NSControlView" ref="52942477"/>
|
||||
<object class="NSColor" key="NSBackgroundColor" id="738791573">
|
||||
<int key="NSColorSpace">6</int>
|
||||
<string key="NSCatalogName">System</string>
|
||||
<string key="NSColorName">controlColor</string>
|
||||
<object class="NSColor" key="NSColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MC42NjY2NjY2OQA</bytes>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSColor" key="NSTextColor" id="909242260">
|
||||
<int key="NSColorSpace">6</int>
|
||||
<string key="NSCatalogName">System</string>
|
||||
<string key="NSColorName">controlTextColor</string>
|
||||
<object class="NSColor" key="NSColor" id="488201583">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MAA</bytes>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSImageView" id="131954859">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">268</int>
|
||||
<object class="NSMutableSet" key="NSDragTypes">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMutableArray" key="set.sortedObjects">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>Apple PDF pasteboard type</string>
|
||||
<string>Apple PICT pasteboard type</string>
|
||||
<string>Apple PNG pasteboard type</string>
|
||||
<string>NSFilenamesPboardType</string>
|
||||
<string>NeXT Encapsulated PostScript v1.2 pasteboard type</string>
|
||||
<string>NeXT TIFF v4.0 pasteboard type</string>
|
||||
</object>
|
||||
</object>
|
||||
<string key="NSFrame">{{20, 269}, {64, 64}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSImageCell" key="NSCell" id="863447683">
|
||||
<int key="NSCellFlags">130560</int>
|
||||
<int key="NSCellFlags2">33554432</int>
|
||||
<object class="NSCustomResource" key="NSContents">
|
||||
<string key="NSClassName">NSImage</string>
|
||||
<string key="NSResourceName">NSApplicationIcon</string>
|
||||
</object>
|
||||
<int key="NSAlign">0</int>
|
||||
<int key="NSScale">0</int>
|
||||
<int key="NSStyle">0</int>
|
||||
<bool key="NSAnimates">NO</bool>
|
||||
</object>
|
||||
<bool key="NSEditable">YES</bool>
|
||||
</object>
|
||||
<object class="NSTextField" id="547141541">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">266</int>
|
||||
<string key="NSFrame">{{17, 191}, {450, 70}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSTextFieldCell" key="NSCell" id="857260085">
|
||||
<int key="NSCellFlags">67239424</int>
|
||||
<int key="NSCellFlags2">272760832</int>
|
||||
<string type="base64-UTF8" key="NSContents">RE8gTk9UIExPQ0FMSVpFLiBUaGUgc3lzdGVtIGFuZCBvdGhlciBhcHBsaWNhdGlvbnMgaGF2ZSBub3Qg
|
||||
YmVlbiBhZmZlY3RlZC4gQSByZXBvcnQgaGFzIGJlZW4gY3JlYXRlZCB0aGF0IHlvdSBjYW4gc2VuZCB0
|
||||
byA8UmVhbGx5IExvbmcgQ29tcGFueSBOYW1lPiB0byBoZWxwIGlkZW50aWZ5IHRoZSBwcm9ibGVtLgoK
|
||||
UGxlYXNlIGhlbHAgdXMgZml4IHRoZSBwcm9ibGVtIGJ5IGRlc2NyaWJpbmcgd2hhdCBoYXBwZW5lZCBi
|
||||
ZWZvcmUgdGhlIGNyYXNoLg</string>
|
||||
<object class="NSFont" key="NSSupport" id="26">
|
||||
<string key="NSName">LucidaGrande</string>
|
||||
<double key="NSSize">1.100000e+01</double>
|
||||
<int key="NSfFlags">3100</int>
|
||||
</object>
|
||||
<reference key="NSControlView" ref="547141541"/>
|
||||
<reference key="NSBackgroundColor" ref="738791573"/>
|
||||
<reference key="NSTextColor" ref="909242260"/>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSTextField" id="637803025">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">290</int>
|
||||
<string key="NSFrame">{{17, 85}, {450, 28}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSTextFieldCell" key="NSCell" id="862965674">
|
||||
<int key="NSCellFlags">67239424</int>
|
||||
<int key="NSCellFlags2">272760832</int>
|
||||
<string key="NSContents">DO NOT LOCALIZE. Providing your email address is optional and will allow us contact you in case we need more details.</string>
|
||||
<reference key="NSSupport" ref="26"/>
|
||||
<reference key="NSControlView" ref="637803025"/>
|
||||
<reference key="NSBackgroundColor" ref="738791573"/>
|
||||
<reference key="NSTextColor" ref="909242260"/>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSButton" id="506323760">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">289</int>
|
||||
<string key="NSFrame">{{353, 12}, {117, 32}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSButtonCell" key="NSCell" id="555878343">
|
||||
<int key="NSCellFlags">67239424</int>
|
||||
<int key="NSCellFlags2">134217728</int>
|
||||
<string key="NSContents">Send Report</string>
|
||||
<object class="NSFont" key="NSSupport" id="890637240">
|
||||
<string key="NSName">LucidaGrande</string>
|
||||
<double key="NSSize">1.300000e+01</double>
|
||||
<int key="NSfFlags">1044</int>
|
||||
</object>
|
||||
<reference key="NSControlView" ref="506323760"/>
|
||||
<int key="NSButtonFlags">-2038284033</int>
|
||||
<int key="NSButtonFlags2">129</int>
|
||||
<reference key="NSAlternateImage" ref="890637240"/>
|
||||
<string key="NSAlternateContents"/>
|
||||
<string type="base64-UTF8" key="NSKeyEquivalent">DQ</string>
|
||||
<int key="NSPeriodicDelay">200</int>
|
||||
<int key="NSPeriodicInterval">25</int>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSButton" id="1066255572">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">289</int>
|
||||
<string key="NSFrame">{{243, 12}, {110, 32}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSButtonCell" key="NSCell" id="910201563">
|
||||
<int key="NSCellFlags">67239424</int>
|
||||
<int key="NSCellFlags2">134217728</int>
|
||||
<string key="NSContents">Cancel</string>
|
||||
<reference key="NSSupport" ref="890637240"/>
|
||||
<reference key="NSControlView" ref="1066255572"/>
|
||||
<int key="NSButtonFlags">-2038284033</int>
|
||||
<int key="NSButtonFlags2">129</int>
|
||||
<reference key="NSAlternateImage" ref="890637240"/>
|
||||
<string key="NSAlternateContents"/>
|
||||
<string type="base64-UTF8" key="NSKeyEquivalent">Gw</string>
|
||||
<int key="NSPeriodicDelay">200</int>
|
||||
<int key="NSPeriodicInterval">25</int>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSTextField" id="834332784">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">290</int>
|
||||
<string key="NSFrame">{{59, 58}, {195, 19}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSTextFieldCell" key="NSCell" id="454024475">
|
||||
<int key="NSCellFlags">-1804468671</int>
|
||||
<int key="NSCellFlags2">272761856</int>
|
||||
<string key="NSContents">preston.jackson@gmail.com</string>
|
||||
<reference key="NSSupport" ref="26"/>
|
||||
<string key="NSPlaceholderString">optional</string>
|
||||
<reference key="NSControlView" ref="834332784"/>
|
||||
<bool key="NSDrawsBackground">YES</bool>
|
||||
<object class="NSColor" key="NSBackgroundColor" id="181834562">
|
||||
<int key="NSColorSpace">6</int>
|
||||
<string key="NSCatalogName">System</string>
|
||||
<string key="NSColorName">textBackgroundColor</string>
|
||||
<object class="NSColor" key="NSColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MQA</bytes>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSColor" key="NSTextColor" id="332510420">
|
||||
<int key="NSColorSpace">6</int>
|
||||
<string key="NSCatalogName">System</string>
|
||||
<string key="NSColorName">textColor</string>
|
||||
<reference key="NSColor" ref="488201583"/>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSTextField" id="1001751188">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">292</int>
|
||||
<string key="NSFrame">{{17, 60}, {37, 14}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSTextFieldCell" key="NSCell" id="220926093">
|
||||
<int key="NSCellFlags">68288064</int>
|
||||
<int key="NSCellFlags2">71435264</int>
|
||||
<string key="NSContents">Email:</string>
|
||||
<reference key="NSSupport" ref="26"/>
|
||||
<reference key="NSControlView" ref="1001751188"/>
|
||||
<reference key="NSBackgroundColor" ref="738791573"/>
|
||||
<reference key="NSTextColor" ref="909242260"/>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSButton" id="645396128">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">289</int>
|
||||
<string key="NSFrame">{{352, 59}, {16, 17}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSButtonCell" key="NSCell" id="776409024">
|
||||
<int key="NSCellFlags">-2080244224</int>
|
||||
<int key="NSCellFlags2">262144</int>
|
||||
<string key="NSContents">Privacy Policy</string>
|
||||
<object class="NSFont" key="NSSupport">
|
||||
<string key="NSName">LucidaGrande</string>
|
||||
<double key="NSSize">9.000000e+00</double>
|
||||
<int key="NSfFlags">3614</int>
|
||||
</object>
|
||||
<reference key="NSControlView" ref="645396128"/>
|
||||
<int key="NSButtonFlags">-2040250113</int>
|
||||
<int key="NSButtonFlags2">36</int>
|
||||
<object class="NSCustomResource" key="NSNormalImage">
|
||||
<string key="NSClassName">NSImage</string>
|
||||
<string key="NSResourceName">NSFollowLinkFreestandingTemplate</string>
|
||||
</object>
|
||||
<string key="NSAlternateContents"/>
|
||||
<string key="NSKeyEquivalent"/>
|
||||
<int key="NSPeriodicDelay">400</int>
|
||||
<int key="NSPeriodicInterval">75</int>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSTextField" id="271427294">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">289</int>
|
||||
<string key="NSFrame">{{259, 60}, {89, 14}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSTextFieldCell" key="NSCell" id="718717750">
|
||||
<int key="NSCellFlags">68288064</int>
|
||||
<int key="NSCellFlags2">71435264</int>
|
||||
<string key="NSContents">Privacy Policy</string>
|
||||
<reference key="NSSupport" ref="26"/>
|
||||
<reference key="NSControlView" ref="271427294"/>
|
||||
<reference key="NSBackgroundColor" ref="738791573"/>
|
||||
<reference key="NSTextColor" ref="909242260"/>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSTextField" id="652207274">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<string key="NSFrame">{{20, 124}, {444, 61}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSTextFieldCell" key="NSCell" id="748395329">
|
||||
<int key="NSCellFlags">341966337</int>
|
||||
<int key="NSCellFlags2">272760832</int>
|
||||
<string key="NSContents">DO NOT LOCALIZE: Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 </string>
|
||||
<reference key="NSSupport" ref="26"/>
|
||||
<reference key="NSControlView" ref="652207274"/>
|
||||
<bool key="NSDrawsBackground">YES</bool>
|
||||
<reference key="NSBackgroundColor" ref="181834562"/>
|
||||
<reference key="NSTextColor" ref="332510420"/>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<string key="NSFrameSize">{484, 353}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
</object>
|
||||
<string key="NSScreenRect">{{0, 0}, {1680, 1028}}</string>
|
||||
<string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<object class="NSMutableArray" key="connectionRecords">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">alertWindow</string>
|
||||
<reference key="source" ref="1001"/>
|
||||
<reference key="destination" ref="1005"/>
|
||||
</object>
|
||||
<int key="connectionID">42</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">sendReport:</string>
|
||||
<reference key="source" ref="1001"/>
|
||||
<reference key="destination" ref="506323760"/>
|
||||
</object>
|
||||
<int key="connectionID">45</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">cancel:</string>
|
||||
<reference key="source" ref="1001"/>
|
||||
<reference key="destination" ref="1066255572"/>
|
||||
</object>
|
||||
<int key="connectionID">46</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">showPrivacyPolicy:</string>
|
||||
<reference key="source" ref="1001"/>
|
||||
<reference key="destination" ref="645396128"/>
|
||||
</object>
|
||||
<int key="connectionID">53</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBBindingConnection" key="connection">
|
||||
<string key="label">value: headerMessage</string>
|
||||
<reference key="source" ref="52942477"/>
|
||||
<reference key="destination" ref="1001"/>
|
||||
<object class="NSNibBindingConnector" key="connector">
|
||||
<reference key="NSSource" ref="52942477"/>
|
||||
<reference key="NSDestination" ref="1001"/>
|
||||
<string key="NSLabel">value: headerMessage</string>
|
||||
<string key="NSBinding">value</string>
|
||||
<string key="NSKeyPath">headerMessage</string>
|
||||
<int key="NSNibBindingConnectorVersion">2</int>
|
||||
</object>
|
||||
</object>
|
||||
<int key="connectionID">85</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBBindingConnection" key="connection">
|
||||
<string key="label">value: reportMessage</string>
|
||||
<reference key="source" ref="547141541"/>
|
||||
<reference key="destination" ref="1001"/>
|
||||
<object class="NSNibBindingConnector" key="connector">
|
||||
<reference key="NSSource" ref="547141541"/>
|
||||
<reference key="NSDestination" ref="1001"/>
|
||||
<string key="NSLabel">value: reportMessage</string>
|
||||
<string key="NSBinding">value</string>
|
||||
<string key="NSKeyPath">reportMessage</string>
|
||||
<int key="NSNibBindingConnectorVersion">2</int>
|
||||
</object>
|
||||
</object>
|
||||
<int key="connectionID">86</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBBindingConnection" key="connection">
|
||||
<string key="label">value: emailMessage</string>
|
||||
<reference key="source" ref="637803025"/>
|
||||
<reference key="destination" ref="1001"/>
|
||||
<object class="NSNibBindingConnector" key="connector">
|
||||
<reference key="NSSource" ref="637803025"/>
|
||||
<reference key="NSDestination" ref="1001"/>
|
||||
<string key="NSLabel">value: emailMessage</string>
|
||||
<string key="NSBinding">value</string>
|
||||
<string key="NSKeyPath">emailMessage</string>
|
||||
<int key="NSNibBindingConnectorVersion">2</int>
|
||||
</object>
|
||||
</object>
|
||||
<int key="connectionID">87</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBBindingConnection" key="connection">
|
||||
<string key="label">value: emailValue</string>
|
||||
<reference key="source" ref="834332784"/>
|
||||
<reference key="destination" ref="1001"/>
|
||||
<object class="NSNibBindingConnector" key="connector">
|
||||
<reference key="NSSource" ref="834332784"/>
|
||||
<reference key="NSDestination" ref="1001"/>
|
||||
<string key="NSLabel">value: emailValue</string>
|
||||
<string key="NSBinding">value</string>
|
||||
<string key="NSKeyPath">emailValue</string>
|
||||
<object class="NSDictionary" key="NSOptions">
|
||||
<string key="NS.key.0">NSNullPlaceholder</string>
|
||||
<string key="NS.object.0">optional</string>
|
||||
</object>
|
||||
<int key="NSNibBindingConnectorVersion">2</int>
|
||||
</object>
|
||||
</object>
|
||||
<int key="connectionID">90</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">initialFirstResponder</string>
|
||||
<reference key="source" ref="1005"/>
|
||||
<reference key="destination" ref="506323760"/>
|
||||
</object>
|
||||
<int key="connectionID">91</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBBindingConnection" key="connection">
|
||||
<string key="label">value: commentsValue</string>
|
||||
<reference key="source" ref="652207274"/>
|
||||
<reference key="destination" ref="1001"/>
|
||||
<object class="NSNibBindingConnector" key="connector">
|
||||
<reference key="NSSource" ref="652207274"/>
|
||||
<reference key="NSDestination" ref="1001"/>
|
||||
<string key="NSLabel">value: commentsValue</string>
|
||||
<string key="NSBinding">value</string>
|
||||
<string key="NSKeyPath">commentsValue</string>
|
||||
<object class="NSDictionary" key="NSOptions">
|
||||
<string key="NS.key.0">NSNullPlaceholder</string>
|
||||
<string key="NS.object.0">optional comments</string>
|
||||
</object>
|
||||
<int key="NSNibBindingConnectorVersion">2</int>
|
||||
</object>
|
||||
</object>
|
||||
<int key="connectionID">124</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">nextKeyView</string>
|
||||
<reference key="source" ref="834332784"/>
|
||||
<reference key="destination" ref="506323760"/>
|
||||
</object>
|
||||
<int key="connectionID">125</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">nextKeyView</string>
|
||||
<reference key="source" ref="652207274"/>
|
||||
<reference key="destination" ref="834332784"/>
|
||||
</object>
|
||||
<int key="connectionID">126</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">nextKeyView</string>
|
||||
<reference key="source" ref="506323760"/>
|
||||
<reference key="destination" ref="652207274"/>
|
||||
</object>
|
||||
<int key="connectionID">127</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">delegate</string>
|
||||
<reference key="source" ref="652207274"/>
|
||||
<reference key="destination" ref="1001"/>
|
||||
</object>
|
||||
<int key="connectionID">128</int>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<object class="NSArray" key="orderedObjects">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<object class="NSArray" key="object" id="1002">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<reference key="children" ref="1000"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-2</int>
|
||||
<reference key="object" ref="1001"/>
|
||||
<reference key="parent" ref="1002"/>
|
||||
<string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-1</int>
|
||||
<reference key="object" ref="1003"/>
|
||||
<reference key="parent" ref="1002"/>
|
||||
<string key="objectName">First Responder</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-3</int>
|
||||
<reference key="object" ref="1004"/>
|
||||
<reference key="parent" ref="1002"/>
|
||||
<string key="objectName">Application</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">1</int>
|
||||
<reference key="object" ref="1005"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="1006"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1002"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">2</int>
|
||||
<reference key="object" ref="1006"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="131954859"/>
|
||||
<reference ref="52942477"/>
|
||||
<reference ref="652207274"/>
|
||||
<reference ref="637803025"/>
|
||||
<reference ref="1001751188"/>
|
||||
<reference ref="834332784"/>
|
||||
<reference ref="271427294"/>
|
||||
<reference ref="645396128"/>
|
||||
<reference ref="506323760"/>
|
||||
<reference ref="1066255572"/>
|
||||
<reference ref="547141541"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1005"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">3</int>
|
||||
<reference key="object" ref="52942477"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="237530958"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">4</int>
|
||||
<reference key="object" ref="237530958"/>
|
||||
<reference key="parent" ref="52942477"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">6</int>
|
||||
<reference key="object" ref="131954859"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="863447683"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">7</int>
|
||||
<reference key="object" ref="863447683"/>
|
||||
<reference key="parent" ref="131954859"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">8</int>
|
||||
<reference key="object" ref="547141541"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="857260085"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">9</int>
|
||||
<reference key="object" ref="857260085"/>
|
||||
<reference key="parent" ref="547141541"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">12</int>
|
||||
<reference key="object" ref="506323760"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="555878343"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">13</int>
|
||||
<reference key="object" ref="555878343"/>
|
||||
<reference key="parent" ref="506323760"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">14</int>
|
||||
<reference key="object" ref="1066255572"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="910201563"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">15</int>
|
||||
<reference key="object" ref="910201563"/>
|
||||
<reference key="parent" ref="1066255572"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">18</int>
|
||||
<reference key="object" ref="834332784"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="454024475"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">19</int>
|
||||
<reference key="object" ref="454024475"/>
|
||||
<reference key="parent" ref="834332784"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">20</int>
|
||||
<reference key="object" ref="1001751188"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="220926093"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">21</int>
|
||||
<reference key="object" ref="220926093"/>
|
||||
<reference key="parent" ref="1001751188"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">48</int>
|
||||
<reference key="object" ref="645396128"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="776409024"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">49</int>
|
||||
<reference key="object" ref="776409024"/>
|
||||
<reference key="parent" ref="645396128"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">58</int>
|
||||
<reference key="object" ref="637803025"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="862965674"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">59</int>
|
||||
<reference key="object" ref="862965674"/>
|
||||
<reference key="parent" ref="637803025"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">66</int>
|
||||
<reference key="object" ref="271427294"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="718717750"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">67</int>
|
||||
<reference key="object" ref="718717750"/>
|
||||
<reference key="parent" ref="271427294"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">116</int>
|
||||
<reference key="object" ref="652207274"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="748395329"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">117</int>
|
||||
<reference key="object" ref="748395329"/>
|
||||
<reference key="parent" ref="652207274"/>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="flattenedProperties">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMutableArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>-1.IBPluginDependency</string>
|
||||
<string>-2.IBPluginDependency</string>
|
||||
<string>-3.IBPluginDependency</string>
|
||||
<string>1.IBEditorWindowLastContentRect</string>
|
||||
<string>1.IBPluginDependency</string>
|
||||
<string>1.IBViewEditorWindowController.showingBoundsRectangles</string>
|
||||
<string>1.IBViewEditorWindowController.showingLayoutRectangles</string>
|
||||
<string>1.IBWindowTemplateEditedContentRect</string>
|
||||
<string>1.NSWindowTemplate.visibleAtLaunch</string>
|
||||
<string>1.WindowOrigin</string>
|
||||
<string>1.editorWindowContentRectSynchronizationRect</string>
|
||||
<string>116.IBPluginDependency</string>
|
||||
<string>117.IBPluginDependency</string>
|
||||
<string>12.IBPluginDependency</string>
|
||||
<string>13.IBPluginDependency</string>
|
||||
<string>14.IBPluginDependency</string>
|
||||
<string>15.IBPluginDependency</string>
|
||||
<string>18.IBPluginDependency</string>
|
||||
<string>19.IBPluginDependency</string>
|
||||
<string>2.IBPluginDependency</string>
|
||||
<string>2.IBUserGuides</string>
|
||||
<string>20.IBPluginDependency</string>
|
||||
<string>21.IBPluginDependency</string>
|
||||
<string>3.IBPluginDependency</string>
|
||||
<string>4.IBPluginDependency</string>
|
||||
<string>48.IBPluginDependency</string>
|
||||
<string>49.IBPluginDependency</string>
|
||||
<string>58.IBPluginDependency</string>
|
||||
<string>59.IBPluginDependency</string>
|
||||
<string>6.IBPluginDependency</string>
|
||||
<string>66.IBPluginDependency</string>
|
||||
<string>67.IBPluginDependency</string>
|
||||
<string>7.IBPluginDependency</string>
|
||||
<string>8.IBPluginDependency</string>
|
||||
<string>9.IBPluginDependency</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>{{641, 409}, {484, 353}}</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<integer value="0" id="6"/>
|
||||
<reference ref="6"/>
|
||||
<string>{{641, 409}, {484, 353}}</string>
|
||||
<reference ref="6"/>
|
||||
<string>{196, 240}</string>
|
||||
<string>{{357, 418}, {480, 270}}</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<object class="NSMutableArray">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="IBUserGuide">
|
||||
<reference key="view" ref="1006"/>
|
||||
<float key="location">1.120000e+02</float>
|
||||
<int key="affinity">1</int>
|
||||
</object>
|
||||
</object>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="unlocalizedProperties">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
</object>
|
||||
<nil key="activeLocalization"/>
|
||||
<object class="NSMutableDictionary" key="localizations">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
</object>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">128</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">Reporter</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<object class="NSMutableDictionary" key="actions">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMutableArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>cancel:</string>
|
||||
<string>sendReport:</string>
|
||||
<string>showPrivacyPolicy:</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>id</string>
|
||||
<string>id</string>
|
||||
<string>id</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="outlets">
|
||||
<string key="NS.key.0">alertWindow</string>
|
||||
<string key="NS.object.0">NSWindow</string>
|
||||
</object>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">sender/crash_report_sender.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.LastKnownRelativeProjectPath">../../Breakpad.xcodeproj</string>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
</data>
|
||||
</archive>
|
||||
BIN
src/client/mac/sender/English.lproj/Localizable.strings
Normal file
BIN
src/client/mac/sender/English.lproj/Localizable.strings
Normal file
Binary file not shown.
2489
src/client/mac/sender/ReporterIcon.graffle
Normal file
2489
src/client/mac/sender/ReporterIcon.graffle
Normal file
File diff suppressed because it is too large
Load Diff
BIN
src/client/mac/sender/ReporterIcon.icns
Normal file
BIN
src/client/mac/sender/ReporterIcon.icns
Normal file
Binary file not shown.
24
src/client/mac/sender/crash_report_sender-Info.plist
Normal file
24
src/client/mac/sender/crash_report_sender-Info.plist
Normal file
@@ -0,0 +1,24 @@
|
||||
<?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>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.Breakpad.${PRODUCT_NAME:identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
89
src/client/mac/sender/crash_report_sender.h
Normal file
89
src/client/mac/sender/crash_report_sender.h
Normal file
@@ -0,0 +1,89 @@
|
||||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This component uses the HTTPMultipartUpload of the breakpad project to send
|
||||
// the minidump and associated data to the crash reporting servers.
|
||||
// It will perform throttling based on the parameters passed to it and will
|
||||
// prompt the user to send the minidump.
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
#include "client/mac/Framework/Breakpad.h"
|
||||
|
||||
#define kClientIdPreferenceKey @"clientid"
|
||||
|
||||
@interface Reporter : NSObject {
|
||||
@public
|
||||
IBOutlet NSWindow *alertWindow; // The alert window
|
||||
|
||||
// Values bound in the XIB
|
||||
NSString *headerMessage_; // Message notifying of the crash
|
||||
NSString *reportMessage_; // Message explaining the crash report
|
||||
NSString *commentsValue_; // Comments from the user
|
||||
NSString *emailMessage_; // Message requesting user email
|
||||
NSString *emailValue_; // Email from the user
|
||||
|
||||
@private
|
||||
int configFile_; // File descriptor for config file
|
||||
NSMutableDictionary *parameters_; // Key value pairs of data (STRONG)
|
||||
NSData *minidumpContents_; // The data in the minidump (STRONG)
|
||||
NSData *logFileData_; // An NSdata for the tar, bz2'd log file
|
||||
}
|
||||
|
||||
// Stops the modal panel with an NSAlertDefaultReturn value. This is the action
|
||||
// invoked by the "Send Report" button.
|
||||
- (IBAction)sendReport:(id)sender;
|
||||
// Stops the modal panel with an NSAlertAlternateReturn value. This is the
|
||||
// action invoked by the "Cancel" button.
|
||||
- (IBAction)cancel:(id)sender;
|
||||
// Opens the Google Privacy Policy in the default web browser.
|
||||
- (IBAction)showPrivacyPolicy:(id)sender;
|
||||
|
||||
// Delegate methods for the NSTextField for comments. We want to capture the
|
||||
// Return key and use it to send the message when no text has been entered.
|
||||
// Otherwise, we want Return to add a carriage return to the comments field.
|
||||
- (BOOL)control:(NSControl*)control textView:(NSTextView*)textView
|
||||
doCommandBySelector:(SEL)commandSelector;
|
||||
|
||||
// Accessors to make bindings work
|
||||
- (NSString *)headerMessage;
|
||||
- (void)setHeaderMessage:(NSString *)value;
|
||||
|
||||
- (NSString *)reportMessage;
|
||||
- (void)setReportMessage:(NSString *)value;
|
||||
|
||||
- (NSString *)commentsValue;
|
||||
- (void)setCommentsValue:(NSString *)value;
|
||||
|
||||
- (NSString *)emailMessage;
|
||||
- (void)setEmailMessage:(NSString *)value;
|
||||
|
||||
- (NSString *)emailValue;
|
||||
- (void)setEmailValue:(NSString *)value;
|
||||
@end
|
||||
762
src/client/mac/sender/crash_report_sender.m
Normal file
762
src/client/mac/sender/crash_report_sender.m
Normal file
@@ -0,0 +1,762 @@
|
||||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#import <pwd.h>
|
||||
#import <sys/stat.h>
|
||||
#import <unistd.h>
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
|
||||
#import "common/mac/HTTPMultipartUpload.h"
|
||||
|
||||
#import "crash_report_sender.h"
|
||||
#import "common/mac/GTMLogger.h"
|
||||
|
||||
#define kLastSubmission @"LastSubmission"
|
||||
const int kMinidumpFileLengthLimit = 800000;
|
||||
|
||||
#define kApplePrefsSyncExcludeAllKey @"com.apple.PreferenceSync.ExcludeAllSyncKeys"
|
||||
|
||||
@interface Reporter(PrivateMethods)
|
||||
+ (uid_t)consoleUID;
|
||||
|
||||
- (id)initWithConfigurationFD:(int)fd;
|
||||
|
||||
- (NSString *)readString;
|
||||
- (NSData *)readData:(ssize_t)length;
|
||||
|
||||
- (BOOL)readConfigurationData;
|
||||
- (BOOL)readMinidumpData;
|
||||
- (BOOL)readLogFileData;
|
||||
|
||||
- (BOOL)askUserPermissionToSend:(BOOL)shouldSubmitReport;
|
||||
- (BOOL)shouldSubmitReport;
|
||||
|
||||
// Run an alert window with the given timeout. Returns NSAlertButtonDefault if
|
||||
// the timeout is exceeded. A timeout of 0 queues the message immediately in the
|
||||
// modal run loop.
|
||||
- (int)runModalWindow:(NSWindow*)window withTimeout:(NSTimeInterval)timeout;
|
||||
|
||||
- (NSString*)clientID;
|
||||
@end
|
||||
|
||||
@implementation Reporter
|
||||
//=============================================================================
|
||||
+ (uid_t)consoleUID {
|
||||
SCDynamicStoreRef store =
|
||||
SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("Reporter"), NULL, NULL);
|
||||
uid_t uid = -2; // Default to "nobody"
|
||||
if (store) {
|
||||
CFStringRef user = SCDynamicStoreCopyConsoleUser(store, &uid, NULL);
|
||||
|
||||
if (user)
|
||||
CFRelease(user);
|
||||
else
|
||||
uid = -2;
|
||||
|
||||
CFRelease(store);
|
||||
}
|
||||
|
||||
return uid;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (id)initWithConfigurationFD:(int)fd {
|
||||
if ((self = [super init])) {
|
||||
configFile_ = fd;
|
||||
}
|
||||
|
||||
// Because the reporter is embedded in the framework (and many copies
|
||||
// of the framework may exist) its not completely certain that the OS
|
||||
// will obey the com.apple.PreferenceSync.ExcludeAllSyncKeys in our
|
||||
// Info.plist. To make sure, also set the key directly if needed.
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
if (![ud boolForKey:kApplePrefsSyncExcludeAllKey]) {
|
||||
[ud setBool:YES forKey:kApplePrefsSyncExcludeAllKey];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (NSString *)readString {
|
||||
NSMutableString *str = [NSMutableString stringWithCapacity:32];
|
||||
char ch[2] = { 0 };
|
||||
|
||||
while (read(configFile_, &ch[0], 1) == 1) {
|
||||
if (ch[0] == '\n') {
|
||||
// Break if this is the first newline after reading some other string
|
||||
// data.
|
||||
if ([str length])
|
||||
break;
|
||||
} else {
|
||||
[str appendString:[NSString stringWithUTF8String:ch]];
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (NSData *)readData:(ssize_t)length {
|
||||
NSMutableData *data = [NSMutableData dataWithLength:length];
|
||||
char *bytes = (char *)[data bytes];
|
||||
|
||||
if (read(configFile_, bytes, length) != length)
|
||||
return nil;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (BOOL)readConfigurationData {
|
||||
parameters_ = [[NSMutableDictionary alloc] init];
|
||||
|
||||
while (1) {
|
||||
NSString *key = [self readString];
|
||||
|
||||
if (![key length])
|
||||
break;
|
||||
|
||||
// Read the data. Try to convert to a UTF-8 string, or just save
|
||||
// the data
|
||||
NSString *lenStr = [self readString];
|
||||
ssize_t len = [lenStr intValue];
|
||||
NSData *data = [self readData:len];
|
||||
id value = [[NSString alloc] initWithData:data
|
||||
encoding:NSUTF8StringEncoding];
|
||||
|
||||
[parameters_ setObject:value ? value : data forKey:key];
|
||||
[value release];
|
||||
}
|
||||
|
||||
// generate a unique client ID based on this host's MAC address
|
||||
// then add a key/value pair for it
|
||||
NSString *clientID = [self clientID];
|
||||
[parameters_ setObject:clientID forKey:@"guid"];
|
||||
|
||||
close(configFile_);
|
||||
configFile_ = -1;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Per user per machine
|
||||
- (NSString *)clientID {
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
NSString *crashClientID = [ud stringForKey:kClientIdPreferenceKey];
|
||||
if (crashClientID) {
|
||||
return crashClientID;
|
||||
}
|
||||
|
||||
// Otherwise, if we have no client id, generate one!
|
||||
srandom([[NSDate date] timeIntervalSince1970]);
|
||||
long clientId1 = random();
|
||||
long clientId2 = random();
|
||||
long clientId3 = random();
|
||||
crashClientID = [NSString stringWithFormat:@"%x%x%x",
|
||||
clientId1, clientId2, clientId3];
|
||||
|
||||
[ud setObject:crashClientID forKey:kClientIdPreferenceKey];
|
||||
[ud synchronize];
|
||||
return crashClientID;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (BOOL)readLogFileData {
|
||||
unsigned int logFileCounter = 0;
|
||||
|
||||
NSString *logPath;
|
||||
int logFileTailSize = [[parameters_ objectForKey:@BREAKPAD_LOGFILE_UPLOAD_SIZE]
|
||||
intValue];
|
||||
|
||||
NSMutableArray *logFilenames; // An array of NSString, one per log file
|
||||
logFilenames = [[NSMutableArray alloc] init];
|
||||
|
||||
char tmpDirTemplate[80] = "/tmp/CrashUpload-XXXXX";
|
||||
char *tmpDir = mkdtemp(tmpDirTemplate);
|
||||
|
||||
// Construct key names for the keys we expect to contain log file paths
|
||||
for(logFileCounter = 0;; logFileCounter++) {
|
||||
NSString *logFileKey = [NSString stringWithFormat:@"%@%d",
|
||||
@BREAKPAD_LOGFILE_KEY_PREFIX,
|
||||
logFileCounter];
|
||||
|
||||
logPath = [parameters_ objectForKey:logFileKey];
|
||||
|
||||
// They should all be consecutive, so if we don't find one, assume
|
||||
// we're done
|
||||
|
||||
if (!logPath) {
|
||||
break;
|
||||
}
|
||||
|
||||
NSData *entireLogFile = [[NSData alloc] initWithContentsOfFile:logPath];
|
||||
|
||||
if (entireLogFile == nil) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NSRange fileRange;
|
||||
|
||||
// Truncate the log file, only if necessary
|
||||
|
||||
if ([entireLogFile length] <= logFileTailSize) {
|
||||
fileRange = NSMakeRange(0, [entireLogFile length]);
|
||||
} else {
|
||||
fileRange = NSMakeRange([entireLogFile length] - logFileTailSize,
|
||||
logFileTailSize);
|
||||
}
|
||||
|
||||
char tmpFilenameTemplate[100];
|
||||
|
||||
// Generate a template based on the log filename
|
||||
sprintf(tmpFilenameTemplate,"%s/%s-XXXX", tmpDir,
|
||||
[[logPath lastPathComponent] fileSystemRepresentation]);
|
||||
|
||||
char *tmpFile = mktemp(tmpFilenameTemplate);
|
||||
|
||||
NSData *logSubdata = [entireLogFile subdataWithRange:fileRange];
|
||||
NSString *tmpFileString = [NSString stringWithUTF8String:tmpFile];
|
||||
[logSubdata writeToFile:tmpFileString atomically:NO];
|
||||
|
||||
[logFilenames addObject:[tmpFileString lastPathComponent]];
|
||||
[entireLogFile release];
|
||||
}
|
||||
|
||||
if ([logFilenames count] == 0) {
|
||||
[logFilenames release];
|
||||
logFileData_ = nil;
|
||||
return NO;
|
||||
}
|
||||
|
||||
// now, bzip all files into one
|
||||
NSTask *tarTask = [[NSTask alloc] init];
|
||||
|
||||
[tarTask setCurrentDirectoryPath:[NSString stringWithUTF8String:tmpDir]];
|
||||
[tarTask setLaunchPath:@"/usr/bin/tar"];
|
||||
|
||||
NSMutableArray *bzipArgs = [NSMutableArray arrayWithObjects:@"-cjvf",
|
||||
@"log.tar.bz2",nil];
|
||||
[bzipArgs addObjectsFromArray:logFilenames];
|
||||
|
||||
[logFilenames release];
|
||||
|
||||
[tarTask setArguments:bzipArgs];
|
||||
[tarTask launch];
|
||||
[tarTask waitUntilExit];
|
||||
[tarTask release];
|
||||
|
||||
NSString *logTarFile = [NSString stringWithFormat:@"%s/log.tar.bz2",tmpDir];
|
||||
logFileData_ = [[NSData alloc] initWithContentsOfFile:logTarFile];
|
||||
if (logFileData_ == nil) {
|
||||
GTMLoggerDebug(@"Cannot find temp tar log file: %@", logTarFile);
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (BOOL)readMinidumpData {
|
||||
NSString *minidumpDir = [parameters_ objectForKey:@kReporterMinidumpDirectoryKey];
|
||||
NSString *minidumpID = [parameters_ objectForKey:@kReporterMinidumpIDKey];
|
||||
|
||||
if (![minidumpID length])
|
||||
return NO;
|
||||
|
||||
NSString *path = [minidumpDir stringByAppendingPathComponent:minidumpID];
|
||||
path = [path stringByAppendingPathExtension:@"dmp"];
|
||||
|
||||
// check the size of the minidump and limit it to a reasonable size
|
||||
// before attempting to load into memory and upload
|
||||
const char *fileName = [path fileSystemRepresentation];
|
||||
struct stat fileStatus;
|
||||
|
||||
BOOL success = YES;
|
||||
|
||||
if (!stat(fileName, &fileStatus)) {
|
||||
if (fileStatus.st_size > kMinidumpFileLengthLimit) {
|
||||
fprintf(stderr, "Breakpad Reporter: minidump file too large " \
|
||||
"to upload : %d\n", (int)fileStatus.st_size);
|
||||
success = NO;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Breakpad Reporter: unable to determine minidump " \
|
||||
"file length\n");
|
||||
success = NO;
|
||||
}
|
||||
|
||||
if (success) {
|
||||
minidumpContents_ = [[NSData alloc] initWithContentsOfFile:path];
|
||||
success = ([minidumpContents_ length] ? YES : NO);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
// something wrong with the minidump file -- delete it
|
||||
unlink(fileName);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (BOOL)askUserPermissionToSend:(BOOL)shouldSubmitReport {
|
||||
// Send without confirmation
|
||||
if ([[parameters_ objectForKey:@BREAKPAD_SKIP_CONFIRM] isEqualToString:@"YES"]) {
|
||||
GTMLoggerDebug(@"Skipping confirmation and sending report");
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Determine if we should create a text box for user feedback
|
||||
BOOL shouldRequestComments =
|
||||
[[parameters_ objectForKey:@BREAKPAD_REQUEST_COMMENTS]
|
||||
isEqual:@"YES"];
|
||||
|
||||
NSString *display = [parameters_ objectForKey:@BREAKPAD_PRODUCT_DISPLAY];
|
||||
|
||||
if (![display length])
|
||||
display = [parameters_ objectForKey:@BREAKPAD_PRODUCT];
|
||||
|
||||
NSString *vendor = [parameters_ objectForKey:@BREAKPAD_VENDOR];
|
||||
|
||||
if (![vendor length])
|
||||
vendor = @"Vendor not specified";
|
||||
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
[self setHeaderMessage:[NSString stringWithFormat:
|
||||
NSLocalizedStringFromTableInBundle(@"headerFmt", nil,
|
||||
bundle,
|
||||
@""), vendor, display]];
|
||||
NSString *defaultButtonTitle = nil;
|
||||
NSString *otherButtonTitle = nil;
|
||||
NSTimeInterval timeout = 60.0; // timeout value for the user notification
|
||||
|
||||
// Get the localized alert strings
|
||||
// If we're going to submit a report, prompt the user if this is okay.
|
||||
// Otherwise, just let them know that the app crashed.
|
||||
|
||||
if (shouldSubmitReport) {
|
||||
NSString *msgFormat = NSLocalizedStringFromTableInBundle(@"msg",
|
||||
nil,
|
||||
bundle, @"");
|
||||
|
||||
[self setReportMessage:[NSString stringWithFormat:msgFormat, vendor]];
|
||||
|
||||
defaultButtonTitle = NSLocalizedStringFromTableInBundle(@"sendReportButton",
|
||||
nil, bundle, @"");
|
||||
otherButtonTitle = NSLocalizedStringFromTableInBundle(@"cancelButton", nil,
|
||||
bundle, @"");
|
||||
|
||||
// Nominally use the report interval
|
||||
timeout = [[parameters_ objectForKey:@BREAKPAD_REPORT_INTERVAL]
|
||||
floatValue];
|
||||
} else {
|
||||
[self setReportMessage:NSLocalizedStringFromTableInBundle(@"noSendMsg", nil,
|
||||
bundle, @"")];
|
||||
defaultButtonTitle = NSLocalizedStringFromTableInBundle(@"noSendButton",
|
||||
nil, bundle, @"");
|
||||
timeout = 60.0;
|
||||
}
|
||||
// show the notification for at least one minute
|
||||
if (timeout < 60.0) {
|
||||
timeout = 60.0;
|
||||
}
|
||||
|
||||
// Initialize Cocoa, needed to display the alert
|
||||
NSApplicationLoad();
|
||||
|
||||
int buttonPressed = NSAlertAlternateReturn;
|
||||
|
||||
if (shouldRequestComments) {
|
||||
BOOL didLoadNib = [NSBundle loadNibNamed:@"Breakpad" owner:self];
|
||||
if (didLoadNib) {
|
||||
// Append the request for comments to the |reportMessage| string.
|
||||
NSString *commentsMessage =
|
||||
NSLocalizedStringFromTableInBundle(@"commentsMsg", nil, bundle, @"");
|
||||
[self setReportMessage:[NSString stringWithFormat:@"%@\n\n%@",
|
||||
[self reportMessage],
|
||||
commentsMessage]];
|
||||
|
||||
// Add the request for email address.
|
||||
[self setEmailMessage:
|
||||
NSLocalizedStringFromTableInBundle(@"emailMsg", nil, bundle, @"")];
|
||||
|
||||
// Run the alert
|
||||
buttonPressed = [self runModalWindow:alertWindow withTimeout:timeout];
|
||||
|
||||
// Extract info from the user into the parameters_ dictionary
|
||||
if ([self commentsValue]) {
|
||||
[parameters_ setObject:[self commentsValue]
|
||||
forKey:@BREAKPAD_COMMENTS];
|
||||
}
|
||||
if ([self emailValue]) {
|
||||
[parameters_ setObject:[self emailValue]
|
||||
forKey:@BREAKPAD_EMAIL];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Create an alert panel to tell the user something happened
|
||||
NSPanel* alert = NSGetAlertPanel([self headerMessage],
|
||||
[self reportMessage],
|
||||
defaultButtonTitle,
|
||||
otherButtonTitle, nil);
|
||||
|
||||
// Pop the alert with an automatic timeout, and wait for the response
|
||||
buttonPressed = [self runModalWindow:alert withTimeout:timeout];
|
||||
|
||||
// Release the panel memory
|
||||
NSReleaseAlertPanel(alert);
|
||||
}
|
||||
return buttonPressed == NSAlertDefaultReturn;
|
||||
}
|
||||
|
||||
- (int)runModalWindow:(NSWindow*)window withTimeout:(NSTimeInterval)timeout {
|
||||
// Queue a |stopModal| message to be performed in |timeout| seconds.
|
||||
[NSApp performSelector:@selector(stopModal)
|
||||
withObject:nil
|
||||
afterDelay:timeout];
|
||||
|
||||
// Run the window modally and wait for either a |stopModal| message or a
|
||||
// button click.
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
int returnMethod = [NSApp runModalForWindow:window];
|
||||
|
||||
// Cancel the pending |stopModal| message.
|
||||
if (returnMethod != NSRunStoppedResponse) {
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:NSApp
|
||||
selector:@selector(stopModal)
|
||||
object:nil];
|
||||
}
|
||||
return returnMethod;
|
||||
}
|
||||
|
||||
- (IBAction)sendReport:(id)sender {
|
||||
[alertWindow orderOut:self];
|
||||
// Use NSAlertDefaultReturn so that the return value of |runModalWithWindow|
|
||||
// matches the AppKit function NSRunAlertPanel()
|
||||
[NSApp stopModalWithCode:NSAlertDefaultReturn];
|
||||
}
|
||||
|
||||
// UI Button Actions
|
||||
//=============================================================================
|
||||
- (IBAction)cancel:(id)sender {
|
||||
[alertWindow orderOut:self];
|
||||
// Use NSAlertDefaultReturn so that the return value of |runModalWithWindow|
|
||||
// matches the AppKit function NSRunAlertPanel()
|
||||
[NSApp stopModalWithCode:NSAlertAlternateReturn];
|
||||
}
|
||||
|
||||
- (IBAction)showPrivacyPolicy:(id)sender {
|
||||
// Get the localized privacy policy URL and open it in the default browser.
|
||||
NSURL* privacyPolicyURL =
|
||||
[NSURL URLWithString:NSLocalizedStringFromTableInBundle(
|
||||
@"privacyPolicyURL", nil, [NSBundle mainBundle], @"")];
|
||||
[[NSWorkspace sharedWorkspace] openURL:privacyPolicyURL];
|
||||
}
|
||||
|
||||
// Text Field Delegate Methods
|
||||
//=============================================================================
|
||||
- (BOOL)control:(NSControl*)control textView:(NSTextView*)textView
|
||||
doCommandBySelector:(SEL)commandSelector {
|
||||
BOOL result = NO;
|
||||
// If the user has entered text, don't end editing on "return"
|
||||
if (commandSelector == @selector(insertNewline:)
|
||||
&& [[textView string] length] > 0) {
|
||||
[textView insertNewlineIgnoringFieldEditor:self];
|
||||
result = YES;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Accessors
|
||||
//=============================================================================
|
||||
- (NSString *)headerMessage {
|
||||
return [[headerMessage_ retain] autorelease];
|
||||
}
|
||||
|
||||
- (void)setHeaderMessage:(NSString *)value {
|
||||
if (headerMessage_ != value) {
|
||||
[headerMessage_ autorelease];
|
||||
headerMessage_ = [value copy];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)reportMessage {
|
||||
return [[reportMessage_ retain] autorelease];
|
||||
}
|
||||
|
||||
- (void)setReportMessage:(NSString *)value {
|
||||
if (reportMessage_ != value) {
|
||||
[reportMessage_ autorelease];
|
||||
reportMessage_ = [value copy];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)commentsValue {
|
||||
return [[commentsValue_ retain] autorelease];
|
||||
}
|
||||
|
||||
- (void)setCommentsValue:(NSString *)value {
|
||||
if (commentsValue_ != value) {
|
||||
[commentsValue_ autorelease];
|
||||
commentsValue_ = [value copy];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)emailMessage {
|
||||
return [[emailMessage_ retain] autorelease];
|
||||
}
|
||||
|
||||
- (void)setEmailMessage:(NSString *)value {
|
||||
if (emailMessage_ != value) {
|
||||
[emailMessage_ autorelease];
|
||||
emailMessage_ = [value copy];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)emailValue {
|
||||
return [[emailValue_ retain] autorelease];
|
||||
}
|
||||
|
||||
- (void)setEmailValue:(NSString *)value {
|
||||
if (emailValue_ != value) {
|
||||
[emailValue_ autorelease];
|
||||
emailValue_ = [value copy];
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (BOOL)shouldSubmitReport {
|
||||
float interval = [[parameters_ objectForKey:@BREAKPAD_REPORT_INTERVAL]
|
||||
floatValue];
|
||||
NSString *program = [parameters_ objectForKey:@BREAKPAD_PRODUCT];
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
NSMutableDictionary *programDict =
|
||||
[NSMutableDictionary dictionaryWithDictionary:[ud dictionaryForKey:program]];
|
||||
NSNumber *lastTimeNum = [programDict objectForKey:kLastSubmission];
|
||||
NSTimeInterval lastTime = lastTimeNum ? [lastTimeNum floatValue] : 0;
|
||||
NSTimeInterval now = CFAbsoluteTimeGetCurrent();
|
||||
NSTimeInterval spanSeconds = (now - lastTime);
|
||||
|
||||
[programDict setObject:[NSNumber numberWithFloat:now] forKey:kLastSubmission];
|
||||
[ud setObject:programDict forKey:program];
|
||||
[ud synchronize];
|
||||
|
||||
// If we've specified an interval and we're within that time, don't ask the
|
||||
// user if we should report
|
||||
GTMLoggerDebug(@"Reporter Interval: %f", interval);
|
||||
if (interval > spanSeconds) {
|
||||
GTMLoggerDebug(@"Within throttling interval, not sending report");
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (void)report {
|
||||
NSURL *url = [NSURL URLWithString:[parameters_ objectForKey:@BREAKPAD_URL]];
|
||||
HTTPMultipartUpload *upload = [[HTTPMultipartUpload alloc] initWithURL:url];
|
||||
NSMutableDictionary *uploadParameters = [NSMutableDictionary dictionary];
|
||||
|
||||
// Set the known parameters. This should be kept up to date with the
|
||||
// parameters defined in the Breakpad.h list of parameters. The intent
|
||||
// is so that if there's a parameter that's not in this list, we consider
|
||||
// it to be a "user-defined" parameter and we'll upload it to the server.
|
||||
NSSet *knownParameters =
|
||||
[NSSet setWithObjects:@kReporterMinidumpDirectoryKey,
|
||||
@kReporterMinidumpIDKey, @BREAKPAD_PRODUCT_DISPLAY,
|
||||
@BREAKPAD_PRODUCT, @BREAKPAD_VERSION, @BREAKPAD_URL,
|
||||
@BREAKPAD_REPORT_INTERVAL, @BREAKPAD_SKIP_CONFIRM,
|
||||
@BREAKPAD_SEND_AND_EXIT, @BREAKPAD_REPORTER_EXE_LOCATION,
|
||||
@BREAKPAD_INSPECTOR_LOCATION, @BREAKPAD_LOGFILES,
|
||||
@BREAKPAD_LOGFILE_UPLOAD_SIZE, @BREAKPAD_EMAIL,
|
||||
@BREAKPAD_REQUEST_COMMENTS, @BREAKPAD_COMMENTS,
|
||||
@BREAKPAD_VENDOR, nil];
|
||||
|
||||
// Add parameters
|
||||
[uploadParameters setObject:[parameters_ objectForKey:@BREAKPAD_PRODUCT]
|
||||
forKey:@"prod"];
|
||||
[uploadParameters setObject:[parameters_ objectForKey:@BREAKPAD_VERSION]
|
||||
forKey:@"ver"];
|
||||
|
||||
if ([parameters_ objectForKey:@BREAKPAD_EMAIL]) {
|
||||
[uploadParameters setObject:[parameters_ objectForKey:@BREAKPAD_EMAIL] forKey:@"email"];
|
||||
}
|
||||
|
||||
NSString* comments = [parameters_ objectForKey:@BREAKPAD_COMMENTS];
|
||||
if (comments != nil) {
|
||||
[uploadParameters setObject:comments forKey:@"comments"];
|
||||
}
|
||||
// Add any user parameters
|
||||
NSArray *parameterKeys = [parameters_ allKeys];
|
||||
int keyCount = [parameterKeys count];
|
||||
for (int i = 0; i < keyCount; ++i) {
|
||||
NSString *key = [parameterKeys objectAtIndex:i];
|
||||
if (![knownParameters containsObject:key] &&
|
||||
![key hasPrefix:@BREAKPAD_LOGFILE_KEY_PREFIX])
|
||||
[uploadParameters setObject:[parameters_ objectForKey:key] forKey:key];
|
||||
}
|
||||
[upload setParameters:uploadParameters];
|
||||
// Add minidump file
|
||||
if (minidumpContents_) {
|
||||
[upload addFileContents:minidumpContents_ name:@"upload_file_minidump"];
|
||||
|
||||
// Send it
|
||||
NSError *error = nil;
|
||||
NSData *data = [upload send:&error];
|
||||
NSString *result = [[NSString alloc] initWithData:data
|
||||
encoding:NSUTF8StringEncoding];
|
||||
const char *reportID = "ERR";
|
||||
|
||||
if (error)
|
||||
fprintf(stderr, "Breakpad Reporter: Send Error: %s\n",
|
||||
[[error description] UTF8String]);
|
||||
else
|
||||
reportID = [result UTF8String];
|
||||
|
||||
// rename the minidump file according to the id returned from the server
|
||||
NSString *minidumpDir = [parameters_ objectForKey:@kReporterMinidumpDirectoryKey];
|
||||
NSString *minidumpID = [parameters_ objectForKey:@kReporterMinidumpIDKey];
|
||||
|
||||
NSString *srcString = [NSString stringWithFormat:@"%@/%@.dmp",
|
||||
minidumpDir, minidumpID];
|
||||
NSString *destString = [NSString stringWithFormat:@"%@/%s.dmp",
|
||||
minidumpDir, reportID];
|
||||
|
||||
const char *src = [srcString fileSystemRepresentation];
|
||||
const char *dest = [destString fileSystemRepresentation];
|
||||
|
||||
if (rename(src, dest) == 0) {
|
||||
fprintf(stderr, "Breakpad Reporter: Renamed %s to %s after successful " \
|
||||
"upload\n",src, dest);
|
||||
}
|
||||
else {
|
||||
// can't rename - don't worry - it's not important for users
|
||||
fprintf(stderr, "Breakpad Reporter: successful upload report ID = %s\n",
|
||||
reportID );
|
||||
}
|
||||
[result release];
|
||||
}
|
||||
|
||||
if (logFileData_) {
|
||||
HTTPMultipartUpload *logUpload = [[HTTPMultipartUpload alloc] initWithURL:url];
|
||||
|
||||
[uploadParameters setObject:@"log" forKey:@"type"];
|
||||
[logUpload setParameters:uploadParameters];
|
||||
[logUpload addFileContents:logFileData_ name:@"log"];
|
||||
|
||||
NSError *error = nil;
|
||||
NSData *data = [logUpload send:&error];
|
||||
NSString *result = [[NSString alloc] initWithData:data
|
||||
encoding:NSUTF8StringEncoding];
|
||||
[result release];
|
||||
[logUpload release];
|
||||
}
|
||||
|
||||
[upload release];
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
- (void)dealloc {
|
||||
[parameters_ release];
|
||||
[minidumpContents_ release];
|
||||
[logFileData_ release];
|
||||
[super dealloc];
|
||||
}
|
||||
@end
|
||||
|
||||
//=============================================================================
|
||||
int main(int argc, const char *argv[]) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
// The expectation is that there will be one argument which is the path
|
||||
// to the configuration file
|
||||
if (argc != 2) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Open the file before (potentially) switching to console user
|
||||
int configFile = open(argv[1], O_RDONLY, 0600);
|
||||
|
||||
// we want to avoid a build-up of old config files even if they
|
||||
// have been incorrectly written by the framework
|
||||
unlink(argv[1]);
|
||||
|
||||
if (configFile == -1) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Reporter *reporter = [[Reporter alloc] initWithConfigurationFD:configFile];
|
||||
|
||||
// Gather the configuration data
|
||||
if (![reporter readConfigurationData]) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Read the minidump into memory before we (potentially) switch from the
|
||||
// root user
|
||||
[reporter readMinidumpData];
|
||||
|
||||
[reporter readLogFileData];
|
||||
|
||||
// only submit a report if we have not recently crashed in the past
|
||||
BOOL shouldSubmitReport = [reporter shouldSubmitReport];
|
||||
BOOL okayToSend = NO;
|
||||
|
||||
// ask user if we should send
|
||||
if (shouldSubmitReport) {
|
||||
okayToSend = [reporter askUserPermissionToSend:shouldSubmitReport];
|
||||
}
|
||||
|
||||
// If we're running as root, switch over to nobody
|
||||
if (getuid() == 0 || geteuid() == 0) {
|
||||
struct passwd *pw = getpwnam("nobody");
|
||||
|
||||
// If we can't get a non-root uid, don't send the report
|
||||
if (!pw)
|
||||
exit(0);
|
||||
|
||||
if (setgid(pw->pw_gid) == -1)
|
||||
exit(0);
|
||||
|
||||
if (setuid(pw->pw_uid) == -1)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (okayToSend && shouldSubmitReport) {
|
||||
[reporter report];
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
[reporter release];
|
||||
[pool release];
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user