FileAppender.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /**
  2. * WinPR: Windows Portable Runtime
  3. * WinPR Logger
  4. *
  5. * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include "FileAppender.h"
  23. #include "Message.h"
  24. #include <winpr/crt.h>
  25. #include <winpr/environment.h>
  26. #include <winpr/file.h>
  27. #include <winpr/path.h>
  28. struct _wLogFileAppender
  29. {
  30. WLOG_APPENDER_COMMON();
  31. char* FileName;
  32. char* FilePath;
  33. char* FullFileName;
  34. FILE* FileDescriptor;
  35. };
  36. typedef struct _wLogFileAppender wLogFileAppender;
  37. static SYSTEMTIME LogDateTime = { 0 };
  38. static BOOL WLog_FileAppender_SetOutputFileName(wLogFileAppender* appender, const char* filename)
  39. {
  40. appender->FileName = _strdup(filename);
  41. if (!appender->FileName)
  42. return FALSE;
  43. return TRUE;
  44. }
  45. static BOOL WLog_FileAppender_SetOutputFilePath(wLogFileAppender* appender, const char* filepath)
  46. {
  47. appender->FilePath = _strdup(filepath);
  48. if (!appender->FilePath)
  49. return FALSE;
  50. return TRUE;
  51. }
  52. static BOOL WLog_FileAppender_Open(wLog* log, wLogAppender* appender)
  53. {
  54. wLogFileAppender* fileAppender;
  55. if (!log || !appender)
  56. return FALSE;
  57. fileAppender = (wLogFileAppender*)appender;
  58. if (!fileAppender->FilePath)
  59. {
  60. fileAppender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog");
  61. if (!fileAppender->FilePath)
  62. return FALSE;
  63. }
  64. if (!fileAppender->FileName)
  65. {
  66. SYSTEMTIME localTime;
  67. fileAppender->FileName = (char*) malloc(MAX_PATH);
  68. if (!fileAppender->FileName)
  69. return FALSE;
  70. GetLocalTime(&localTime);
  71. //sprintf_s(fileAppender->FileName, MAX_PATH, "%"PRIu32".log", GetCurrentProcessId());
  72. sprintf_s(fileAppender->FileName, MAX_PATH, "%u%02u%02u.log", localTime.wYear, localTime.wMonth, localTime.wDay);
  73. CopyMemory(&LogDateTime, &localTime, sizeof(SYSTEMTIME));
  74. }
  75. if (!fileAppender->FullFileName)
  76. {
  77. fileAppender->FullFileName = GetCombinedPath(fileAppender->FilePath, fileAppender->FileName);
  78. if (!fileAppender->FullFileName)
  79. return FALSE;
  80. }
  81. if (!PathFileExistsA(fileAppender->FilePath))
  82. {
  83. if (!PathMakePathA(fileAppender->FilePath, 0))
  84. return FALSE;
  85. UnixChangeFileMode(fileAppender->FilePath, 0xFFFF);
  86. }
  87. fileAppender->FileDescriptor = fopen(fileAppender->FullFileName, "a+");
  88. if (!fileAppender->FileDescriptor)
  89. return FALSE;
  90. return TRUE;
  91. }
  92. static BOOL WLog_FileAppender_Close(wLog* log, wLogAppender* appender)
  93. {
  94. wLogFileAppender* fileAppender;
  95. if (!log || !appender)
  96. return FALSE;
  97. fileAppender = (wLogFileAppender*)appender;
  98. if (!fileAppender->FileDescriptor)
  99. return TRUE;
  100. fclose(fileAppender->FileDescriptor);
  101. fileAppender->FileDescriptor = NULL;
  102. return TRUE;
  103. }
  104. static BOOL WLog_FileAppender_ReOpenFileDescriptor(wLog* log, wLogAppender* appender)
  105. {
  106. char format[MAX_PATH];
  107. wLogFileAppender* fileAppender;
  108. BOOL bReopen = FALSE;
  109. SYSTEMTIME localTime;
  110. if (!log || !appender)
  111. return FALSE;
  112. fileAppender = (wLogFileAppender*)appender;
  113. if (!fileAppender->FileDescriptor)
  114. return FALSE;
  115. GetLocalTime(&localTime);
  116. //sprintf_s(format, MAX_PATH, "%"PRIu32".log", GetCurrentProcessId());
  117. //if (!strcmp(fileAppender->FileName, format)) {
  118. // bReopen = TRUE;
  119. //}
  120. //if (!bReopen)
  121. {
  122. }
  123. if (LogDateTime.wYear == 0
  124. ||
  125. !(LogDateTime.wYear == localTime.wYear
  126. && LogDateTime.wMonth == localTime.wMonth
  127. && LogDateTime.wDay == localTime.wDay))
  128. {
  129. if (WLog_FileAppender_Close(log, appender))
  130. {
  131. free(fileAppender->FileName);
  132. fileAppender->FileName = NULL;
  133. free(fileAppender->FullFileName);
  134. fileAppender->FullFileName = NULL;
  135. //fileAppender->FileName = (char*)malloc(MAX_PATH);
  136. //if (!fileAppender->FileName)
  137. // return FALSE;
  138. //sprintf_s(fileAppender->FileName, MAX_PATH, "%u%02u%02u.log", localTime.wYear, localTime.wMonth, localTime.wDay);
  139. if (WLog_FileAppender_Open(log, appender))
  140. {
  141. //CopyMemory(&LogDateTime, &localTime, sizeof(SYSTEMTIME));
  142. return TRUE;
  143. }
  144. }
  145. }
  146. return FALSE;
  147. }
  148. static BOOL WLog_FileAppender_WriteMessage(wLog* log, wLogAppender* appender, wLogMessage* message)
  149. {
  150. FILE* fp;
  151. char prefix[WLOG_MAX_PREFIX_SIZE];
  152. wLogFileAppender* fileAppender;
  153. if (!log || !appender || !message)
  154. return FALSE;
  155. fileAppender = (wLogFileAppender*)appender;
  156. WLog_FileAppender_ReOpenFileDescriptor(log, appender);
  157. fp = fileAppender->FileDescriptor;
  158. if (!fp)
  159. return FALSE;
  160. message->PrefixString = prefix;
  161. WLog_Layout_GetMessagePrefix(log, appender->Layout, message);
  162. fprintf(fp, "%s%s\n", message->PrefixString, message->TextString);
  163. // Debug [3/26/2020 16:43 Gifur]
  164. printf("%s%s\n", message->PrefixString, message->TextString);
  165. fflush(fp); /* slow! */
  166. return TRUE;
  167. }
  168. static int g_DataId = 0;
  169. static BOOL WLog_FileAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
  170. wLogMessage* message)
  171. {
  172. int DataId;
  173. char* FullFileName;
  174. if (!log || !appender || !message)
  175. return FALSE;
  176. DataId = g_DataId++;
  177. FullFileName = WLog_Message_GetOutputFileName(DataId, "dat");
  178. WLog_DataMessage_Write(FullFileName, message->Data, message->Length);
  179. free(FullFileName);
  180. return TRUE;
  181. }
  182. static int g_ImageId = 0;
  183. static BOOL WLog_FileAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
  184. wLogMessage* message)
  185. {
  186. int ImageId;
  187. char* FullFileName;
  188. if (!log || !appender || !message)
  189. return FALSE;
  190. ImageId = g_ImageId++;
  191. FullFileName = WLog_Message_GetOutputFileName(ImageId, "bmp");
  192. WLog_ImageMessage_Write(FullFileName, message->ImageData, message->ImageWidth,
  193. message->ImageHeight, message->ImageBpp);
  194. free(FullFileName);
  195. return TRUE;
  196. }
  197. static BOOL WLog_FileAppender_Set(wLogAppender* appender, const char* setting, void* value)
  198. {
  199. wLogFileAppender* fileAppender = (wLogFileAppender*)appender;
  200. /* Just check the value string is not empty */
  201. if (!value || (strnlen(value, 2) == 0))
  202. return FALSE;
  203. if (!strcmp("outputfilename", setting))
  204. return WLog_FileAppender_SetOutputFileName(fileAppender, (const char*)value);
  205. else if (!strcmp("outputfilepath", setting))
  206. return WLog_FileAppender_SetOutputFilePath(fileAppender, (const char*)value);
  207. else
  208. return FALSE;
  209. return TRUE;
  210. }
  211. static void WLog_FileAppender_Free(wLogAppender* appender)
  212. {
  213. wLogFileAppender* fileAppender = NULL;
  214. if (appender)
  215. {
  216. fileAppender = (wLogFileAppender*)appender;
  217. free(fileAppender->FileName);
  218. free(fileAppender->FilePath);
  219. free(fileAppender->FullFileName);
  220. free(fileAppender);
  221. }
  222. }
  223. wLogAppender* WLog_FileAppender_New(wLog* log)
  224. {
  225. LPSTR env;
  226. LPCSTR name;
  227. DWORD nSize;
  228. wLogFileAppender* FileAppender;
  229. FileAppender = (wLogFileAppender*)calloc(1, sizeof(wLogFileAppender));
  230. if (!FileAppender)
  231. return NULL;
  232. FileAppender->Type = WLOG_APPENDER_FILE;
  233. FileAppender->Open = WLog_FileAppender_Open;
  234. FileAppender->Close = WLog_FileAppender_Close;
  235. FileAppender->WriteMessage = WLog_FileAppender_WriteMessage;
  236. FileAppender->WriteDataMessage = WLog_FileAppender_WriteDataMessage;
  237. FileAppender->WriteImageMessage = WLog_FileAppender_WriteImageMessage;
  238. FileAppender->Free = WLog_FileAppender_Free;
  239. FileAppender->Set = WLog_FileAppender_Set;
  240. name = "WLOG_FILEAPPENDER_OUTPUT_FILE_PATH";
  241. nSize = GetEnvironmentVariableA(name, NULL, 0);
  242. if (nSize)
  243. {
  244. BOOL status;
  245. env = (LPSTR)malloc(nSize);
  246. if (!env)
  247. goto error_free;
  248. if (GetEnvironmentVariableA(name, env, nSize) != nSize - 1)
  249. {
  250. free(env);
  251. goto error_free;
  252. }
  253. status = WLog_FileAppender_SetOutputFilePath(FileAppender, env);
  254. free(env);
  255. if (!status)
  256. goto error_free;
  257. }
  258. name = "WLOG_FILEAPPENDER_OUTPUT_FILE_NAME";
  259. nSize = GetEnvironmentVariableA(name, NULL, 0);
  260. if (nSize)
  261. {
  262. BOOL status = FALSE;
  263. env = (LPSTR)malloc(nSize);
  264. if (!env)
  265. goto error_output_file_name;
  266. if (GetEnvironmentVariableA(name, env, nSize) == nSize - 1)
  267. status = WLog_FileAppender_SetOutputFileName(FileAppender, env);
  268. free(env);
  269. if (!status)
  270. goto error_output_file_name;
  271. }
  272. return (wLogAppender*)FileAppender;
  273. error_output_file_name:
  274. free(FileAppender->FilePath);
  275. error_free:
  276. free(FileAppender);
  277. return NULL;
  278. }