1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2015 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 // Copyright (C) 2015 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "nel/misc/common.h"
27 #include "nel/misc/ucstring.h"
29 #include "nel/misc/report.h"
30 #include "nel/misc/path.h"
31 #include "nel/misc/file.h"
32 #include "nel/misc/system_utils.h"
38 #define NL_REPORT_POST_URL_ENVVAR "NL_REPORT_POST_URL"
40 #define NL_CRASH_REPORT_TOOL "crash_report.exe"
42 #define NL_CRASH_REPORT_TOOL "crash_report"
44 #define NL_DEBUG_REPORT 0
45 // Set to 1 if you want command line report tool
46 #define NL_REPORT_CONSOLE 0
47 // Set to 1 if you want command line report tool even when the debugger is present
48 #define NL_REPORT_CONSOLE_DEBUGGER 1
53 void setReportPostUrl(const char *postUrl
)
56 if (INelContext::isContextInitialised())
57 nldebug("Set report post url to '%s'", postUrl
);
60 SetEnvironmentVariableA(NL_REPORT_POST_URL_ENVVAR
, postUrl
);
62 setenv(NL_REPORT_POST_URL_ENVVAR
, postUrl
, 1);
66 inline const char *getReportPostURL()
71 int res
= GetEnvironmentVariableA(NL_REPORT_POST_URL_ENVVAR
, buf
, sizeof(buf
));
72 if (res
<= 0 || res
> 511) return NULL
;
73 if (buf
[0] == '\0') return NULL
;
76 char *res
= getenv(NL_REPORT_POST_URL_ENVVAR
);
77 if (res
== NULL
|| res
[0] == '\0') return NULL
;
82 TReportResult
report(const std::string
&title
, const std::string
&subject
, const std::string
&body
, const std::string
&attachment
, bool synchronous
, bool sendReport
, TReportResult defaultResult
)
84 std::string reportPath
;
87 std::string reportFile
= getLogDirectory() + NLMISC::toString("nel_report_%u.log", (uint
)time(NULL
));
88 reportPath
= CFile::findNewFile(reportFile
);
90 FILE *f
= nlfopen(reportPath
, "wb"); // write as binary so \n are preserved
95 if (INelContext::isContextInitialised())
96 nldebug("Failed to write report log to '%s'", reportPath
.c_str());
102 size_t written
= fwrite(body
.c_str(), 1, body
.length(), f
);
104 if (written
!= body
.length())
106 nlwarning("Unable to write %u bytes to %s, only %u written", (uint
)body
.length(), reportPath
.c_str(), (uint
)written
);
113 if (((INelContext::isContextInitialised()
114 && INelContext::getInstance().isWindowedApplication())
115 || CSystemUtils::detectWindowedApplication())
116 && CFile::isExists(NL_CRASH_REPORT_TOOL
))
120 if (!reportPath
.empty())
121 params
+= NLMISC::toString(" -log \"%s\"", reportPath
.c_str());
123 if (!subject
.empty())
124 params
+= NLMISC::toString(" -attachment \"%s\"", attachment
.c_str());
127 params
+= NLMISC::toString(" -title \"%s\"", title
.c_str());
129 if (!subject
.empty())
130 params
+= NLMISC::toString(" -subject \"%s\"", subject
.c_str());
132 const char *reportPostUrl
= getReportPostURL();
134 params
+= NLMISC::toString(" -host \"%s\"", reportPostUrl
);
140 params
+= " -sendreport";
144 TReportResult result
= (TReportResult
)NLMISC::launchProgramAndWaitForResult(NL_CRASH_REPORT_TOOL
, params
);
146 if (result
!= ReportAlwaysIgnore
147 && result
!= ReportIgnore
148 && result
!= ReportAbort
149 && result
!= ReportBreak
)
152 if (INelContext::isContextInitialised())
153 nldebug("Return default result, invalid return code %i", (int)result
);
155 return defaultResult
;
161 NLMISC::launchProgram(NL_CRASH_REPORT_TOOL
, params
,
162 NL_DEBUG_REPORT
? INelContext::isContextInitialised() : false); // Only log if required, avoid infinite loop
163 return defaultResult
;
169 if (INelContext::isContextInitialised() && !CFile::isExists(NL_CRASH_REPORT_TOOL
))
170 nldebug("Crash report tool '%s' does not exist", NL_CRASH_REPORT_TOOL
);
172 #if defined(NL_OS_WINDOWS) && !FINAL_VERSION && !NL_REPORT_CONSOLE_DEBUGGER
173 if (IsDebuggerPresent())
175 return defaultResult
;
181 #if NL_REPORT_CONSOLE
182 // An interactive console based report
185 printf("%s\n", title
.c_str());
187 printf("NeL report\n");
189 if (!subject
.empty())
190 printf("\tsubject: '%s'\n", subject
.c_str());
192 printf("\tbody: '%s'\n", reportPath
.c_str());
193 if (!attachment
.empty())
194 printf("\tattachment: '%s'\n", attachment
.c_str());
198 printf("Always Ignore (S), Ignore (I), Abort (A), Break (B)?\n"); // S for Surpress
206 return ReportAlwaysIgnore
;
219 return defaultResult
;
224 return defaultResult
;