PageRenderTime 29ms CodeModel.GetById 9ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/thirdparty/breakpad/client/windows/sender/crash_report_sender.cc

http://github.com/tomahawk-player/tomahawk
C++ | 142 lines | 92 code | 17 blank | 33 comment | 23 complexity | fd4da8d7b3657346843570ac366574e7 MD5 | raw file
  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
 44namespace google_breakpad {
 45
 46static const char kCheckpointSignature[] = "GBP1\n";
 47
 48CrashReportSender::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
 60ReportResult CrashReportSender::SendCrashReport(
 61    const wstring &url, const map<wstring, wstring> &parameters,
 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
 85void 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
102void 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
120int 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
127int 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