OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006, Google Inc. | |
2 // All rights reserved. | |
3 // | |
4 // Redistribution and use in source and binary forms, with or without | |
5 // modification, are permitted provided that the following conditions are | |
6 // met: | |
7 // | |
8 // * Redistributions of source code must retain the above copyright | |
9 // notice, this list of conditions and the following disclaimer. | |
10 // * Redistributions in binary form must reproduce the above | |
11 // copyright notice, this list of conditions and the following disclaimer | |
12 // in the documentation and/or other materials provided with the | |
13 // distribution. | |
14 // * Neither the name of Google Inc. nor the names of its | |
15 // contributors may be used to endorse or promote products derived from | |
16 // this software without specific prior written permission. | |
17 // | |
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 | |
30 // Disable exception handler warnings. | |
31 #pragma warning( disable : 4530 ) | |
32 | |
33 #include <errno.h> | |
34 | |
35 #include "client/windows/sender/crash_report_sender.h" | |
36 #include "common/windows/http_upload.h" | |
37 | |
38 #if _MSC_VER < 1400 // MSVC 2005/8 | |
39 // Older MSVC doesn't have fscanf_s, but they are compatible as long as | |
40 // we don't use the string conversions (%s/%c/%S/%C). | |
41 #define fscanf_s fscanf | |
42 #endif | |
43 | |
44 namespace google_breakpad { | |
45 | |
46 static const char kCheckpointSignature[] = "GBP1\n"; | |
47 | |
48 CrashReportSender::CrashReportSender(const wstring &checkpoint_file) | |
49 : checkpoint_file_(checkpoint_file), | |
50 max_reports_per_day_(-1), | |
51 last_sent_date_(-1), | |
52 reports_sent_(0) { | |
53 FILE *fd; | |
54 if (OpenCheckpointFile(L"r", &fd) == 0) { | |
55 ReadCheckpoint(fd); | |
56 fclose(fd); | |
57 } | |
58 } | |
59 | |
60 ReportResult CrashReportSender::SendCrashReport( | |
61 const wstring &url, const map<wstring, wstring> ¶meters, | |
62 const wstring &dump_file_name, wstring *report_code) { | |
63 int today = GetCurrentDate(); | |
64 if (today == last_sent_date_ && | |
65 max_reports_per_day_ != -1 && | |
66 reports_sent_ >= max_reports_per_day_) { | |
67 return RESULT_THROTTLED; | |
68 } | |
69 | |
70 int http_response = 0; | |
71 bool result = HTTPUpload::SendRequest( | |
72 url, parameters, dump_file_name, L"upload_file_minidump", NULL, report_code, | |
73 &http_response); | |
74 | |
75 if (result) { | |
76 ReportSent(today); | |
77 return RESULT_SUCCEEDED; | |
78 } else if (http_response >= 400 && http_response < 500) { | |
79 return RESULT_REJECTED; | |
80 } else { | |
81 return RESULT_FAILED; | |
82 } | |
83 } | |
84 | |
85 void CrashReportSender::ReadCheckpoint(FILE *fd) { | |
86 char buf[128]; | |
87 if (!fgets(buf, sizeof(buf), fd) || | |
88 strcmp(buf, kCheckpointSignature) != 0) { | |
89 return; | |
90 } | |
91 | |
92 if (fscanf_s(fd, "%d\n", &last_sent_date_) != 1) { | |
93 last_sent_date_ = -1; | |
94 return; | |
95 } | |
96 if (fscanf_s(fd, "%d\n", &reports_sent_) != 1) { | |
97 reports_sent_ = 0; | |
98 return; | |
99 } | |
100 } | |
101 | |
102 void CrashReportSender::ReportSent(int today) { | |
103 // Update the report stats | |
104 if (today != last_sent_date_) { | |
105 last_sent_date_ = today; | |
106 reports_sent_ = 0; | |
107 } | |
108 ++reports_sent_; | |
109 | |
110 // Update the checkpoint file | |
111 FILE *fd; | |
112 if (OpenCheckpointFile(L"w", &fd) == 0) { | |
113 fputs(kCheckpointSignature, fd); | |
114 fprintf(fd, "%d\n", last_sent_date_); | |
115 fprintf(fd, "%d\n", reports_sent_); | |
116 fclose(fd); | |
117 } | |
118 } | |
119 | |
120 int CrashReportSender::GetCurrentDate() const { | |
121 SYSTEMTIME system_time; | |
122 GetSystemTime(&system_time); | |
123 return (system_time.wYear * 10000) + (system_time.wMonth * 100) + | |
124 system_time.wDay; | |
125 } | |
126 | |
127 int CrashReportSender::OpenCheckpointFile(const wchar_t *mode, FILE **fd) { | |
128 if (checkpoint_file_.empty()) { | |
129 return ENOENT; | |
130 } | |
131 #if _MSC_VER >= 1400 // MSVC 2005/8 | |
132 return _wfopen_s(fd, checkpoint_file_.c_str(), mode); | |
133 #else | |
134 *fd = _wfopen(checkpoint_file_.c_str(), mode); | |
135 if (*fd == NULL) { | |
136 return errno; | |
137 } | |
138 return 0; | |
139 #endif | |
140 } | |
141 | |
142 } // namespace google_breakpad | |
OLD | NEW |