Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/filesys_log.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10958 - (hide annotations) (download) (as text)
Sat Oct 7 17:40:16 2023 UTC (6 months ago) by zmatsuo
File MIME type: text/x-c++src
File size: 27979 byte(s)
文字列を返す関数の文字領域を動的確保するよう変更

- 複数スレッドを使用している箇所でログが壊れたり不正な処理で終了することがあった
- ログ出力時に使用していた関数が文字領域を静的に持っていた
- マルチスレッドで使用していると文字領域を破壊することがある
- 返す文字領域を動的にして不要になったらfree()するよう仕様を変更
1 doda 6806 /*
2 nmaya 9048 * (C) 2020- TeraTerm Project
3 doda 6806 * All rights reserved.
4     *
5 doda 6841 * Redistribution and use in source and binary forms, with or without
6     * modification, are permitted provided that the following conditions
7     * are met:
8 doda 6806 *
9 doda 6841 * 1. Redistributions of source code must retain the above copyright
10     * notice, this list of conditions and the following disclaimer.
11     * 2. Redistributions in binary form must reproduce the above copyright
12     * notice, this list of conditions and the following disclaimer in the
13     * documentation and/or other materials provided with the distribution.
14     * 3. The name of the author may not be used to endorse or promote products
15     * derived from this software without specific prior written permission.
16 doda 6806 *
17 doda 6841 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 doda 6806 */
28 maya 3227
29 zmatsuo 8897 /* TERATERM.EXE, log routines */
30 zmatsuo 7526 #include <stdio.h>
31 zmatsuo 8900 #if !defined(_CRTDBG_MAP_ALLOC)
32     #define _CRTDBG_MAP_ALLOC
33     #endif
34     #include <stdlib.h>
35     #include <crtdbg.h>
36 zmatsuo 7526 #include <process.h>
37 zmatsuo 8852 #include <windows.h>
38     #include <htmlhelp.h>
39     #include <assert.h>
40 zmatsuo 7526
41 maya 3227 #include "teraterm.h"
42     #include "tttypes.h"
43     #include "ftdlg.h"
44     #include "ttwinman.h"
45     #include "commlib.h"
46     #include "ttcommon.h"
47     #include "ttlib.h"
48     #include "dlglib.h"
49 doda 3904 #include "vtterm.h"
50 maya 3227 #include "ftlib.h"
51 yutakapon 5392 #include "buffer.h"
52 zmatsuo 8852 #include "helpid.h"
53 zmatsuo 8863 #include "codeconv.h"
54 zmatsuo 8899 #include "asprintf.h"
55 zmatsuo 9857 #include "win32helper.h"
56 yutakapon 5392
57 zmatsuo 8852 #include "filesys_log_res.h"
58 zmatsuo 8900 #include "filesys_log.h"
59 zmatsuo 9103 #include "filesys.h" // for ProtoGetProtoFlag()
60 zmatsuo 8866
61 zmatsuo 9104 #define TitLog L"Log"
62    
63 zmatsuo 8901 /*
64     Line Head flag for timestamping
65     2007.05.24 Gentaro
66     */
67     enum enumLineEnd {
68     Line_Other = 0,
69     Line_LineHead = 1,
70     Line_FileHead = 2,
71     };
72    
73 zmatsuo 8894 typedef struct {
74 zmatsuo 8901 wchar_t *FullName;
75 maya 3227
76 zmatsuo 8901 HANDLE FileHandle;
77     LONG FileSize, ByteCount;
78 maya 6071
79 zmatsuo 8901 DWORD StartTime;
80 maya 3227
81 zmatsuo 8901 enum enumLineEnd eLineEnd;
82 maya 7182
83 zmatsuo 8901 // log rotate
84     int RotateMode; // enum rotate_mode RotateMode;
85     LONG RotateSize;
86     int RotateStep;
87 zmatsuo 8900
88 zmatsuo 8901 HANDLE LogThread;
89     DWORD LogThreadId;
90     HANDLE LogThreadEvent;
91    
92     BOOL IsPause;
93    
94     PFileTransDlg FLogDlg;
95 zmatsuo 8904
96 zmatsuo 8912 LogCode_t log_code;
97     BOOL bom;
98 zmatsuo 8904
99 zmatsuo 9872 BOOL FileLog;
100     BOOL BinLog;
101 zmatsuo 9873 } TFileVar;
102     typedef TFileVar *PFileVar;
103 zmatsuo 8894
104     static PFileVar LogVar = NULL;
105    
106 zmatsuo 8906 static PCHAR cv_LogBuf;
107     static int cv_LogPtr, cv_LStart, cv_LCount;
108     static PCHAR cv_BinBuf;
109     static int cv_BinPtr, cv_BStart, cv_BCount;
110     static int cv_BinSkip;
111    
112 yutakapon 5206 // �x�����������p�X���b�h�����b�Z�[�W
113     #define WM_DPC_LOGTHREAD_SEND (WM_APP + 1)
114    
115 zmatsuo 8897 static void Log1Bin(BYTE b);
116     static void LogBinSkip(int add);
117     static BOOL CreateLogBuf(void);
118     static BOOL CreateBinBuf(void);
119 zmatsuo 8905 void LogPut1(BYTE b);
120 zmatsuo 8907 static void OutputStr(const wchar_t *str);
121 zmatsuo 9873 static void LogToFile(PFileVar fv);
122     static void FLogOutputBOM(PFileVar fv);
123 yutakapon 5206
124 zmatsuo 8894 static BOOL OpenFTDlg_(PFileVar fv)
125 maya 3227 {
126 zmatsuo 8899 PFileTransDlg FTDlg = new CFileTransDlg();
127     if (FTDlg == NULL) {
128     return FALSE;
129     }
130 maya 3227
131 zmatsuo 8899 wchar_t *DlgCaption;
132 zmatsuo 10614 wchar_t *uimsg;
133     GetI18nStrWW("Tera Term", "FILEDLG_TRANS_TITLE_LOG", TitLog, ts.UILanguageFileW, &uimsg);
134 zmatsuo 8899 aswprintf(&DlgCaption, L"Tera Term: %s", uimsg);
135 zmatsuo 10614 free(uimsg);
136 maya 3227
137 zmatsuo 9070 CFileTransDlg::Info info;
138 zmatsuo 10614 info.UILanguageFileW = ts.UILanguageFileW;
139 zmatsuo 9070 info.OpId = CFileTransDlg::OpLog;
140 zmatsuo 8899 info.DlgCaption = DlgCaption;
141 zmatsuo 8911 info.FileName = NULL;
142 zmatsuo 8899 info.FullName = fv->FullName;
143     info.HideDialog = ts.LogHideDialog ? TRUE : FALSE;
144     info.HMainWin = HVTWin;
145     FTDlg->Create(hInst, &info);
146     FTDlg->RefreshNum(0, fv->FileSize, fv->ByteCount);
147 doda 4454
148 zmatsuo 8901 fv->FLogDlg = FTDlg;
149 doda 5383
150 zmatsuo 8899 free(DlgCaption);
151     return TRUE;
152 maya 3227 }
153    
154 zmatsuo 8852 /**
155 zmatsuo 10443 * �t�@�C�������������u������,���O�p
156     * �����������u��������
157     * &h �z�X�g�����u��
158     * &p TCP�|�[�g�������u��
159 zmatsuo 8852 * &u ���O�I���������[�U��
160 zmatsuo 10443 *
161     * @param pcv
162     * @param src �u���������O��������(�t�@�C����)
163     * @return �u������������������
164     * �s�v����������free()��������
165 zmatsuo 8852 */
166 zmatsuo 10444 static wchar_t *ConvertLognameW(const TComVar *pcv, const wchar_t *src)
167 maya 3227 {
168 zmatsuo 10443 const TTTSet *pts = pcv->ts;
169     size_t dest_len = wcslen(src) + 1;
170     wchar_t *dest = (wchar_t *)malloc(sizeof(wchar_t) * dest_len);
171 maya 3227
172 zmatsuo 10443 const wchar_t *s = src;
173     size_t i = 0;
174 maya 3227
175 zmatsuo 10443 while(*s != '\0') {
176     if (*s == '&' && *(s+1) != '\0') {
177     wchar_t c = *(s+1);
178     wchar_t *add_text = NULL;
179     switch (c) {
180     case 'h':
181     s += 2;
182     if (pcv->Open) {
183     switch(pcv->PortType) {
184     case IdTCPIP: {
185     // �z�X�g����IPv6�A�h���X�����A�t�@�C�������g�p������������(:)�����������u��
186     wchar_t *host = ToWcharA(pts->HostName);
187     wchar_t *host_fix = replaceInvalidFileNameCharW(host, '_');
188     free(host);
189     add_text = host_fix;
190     break;
191 maya 3227 }
192 zmatsuo 10443 case IdSerial: {
193     wchar_t *port;
194     aswprintf(&port, L"COM%d", ts.ComPort);
195     add_text = port;
196     break;
197 maya 3227 }
198 zmatsuo 10443 default:
199     ;
200     }
201 maya 3227 }
202     break;
203 zmatsuo 10443 case 'p':
204     s += 2;
205     if (pcv->Open) {
206     if (pcv->PortType == IdTCPIP) {
207     wchar_t *port;
208     aswprintf(&port, L"%d", ts.TCPPort);
209     add_text = port;
210 maya 3473 }
211     }
212     break;
213 zmatsuo 10443 case 'u': {
214     s += 2;
215     wchar_t user[256 + 1]; // 256=UNLEN
216     DWORD l = _countof(user);
217     if (GetUserNameW(user, &l) != 0) {
218 zmatsuo 10468 add_text = _wcsdup(user);
219 maya 6590 }
220     break;
221 maya 3227 }
222 zmatsuo 10443 default:
223     // pass '&'
224     s++;
225     add_text = NULL;
226     break;
227     }
228    
229 zmatsuo 10444 if (add_text != NULL) {
230 zmatsuo 10443 size_t l = wcslen(add_text);
231     dest_len += l;
232     dest = (wchar_t *)realloc(dest, sizeof(wchar_t) * dest_len);
233     wcscpy(&dest[i], add_text);
234 zmatsuo 10444 free(add_text);
235 zmatsuo 10443 i += l;
236     }
237 maya 3227 }
238     else {
239 zmatsuo 10443 dest[i] = *s++;
240     i++;
241 maya 3227 }
242     }
243 zmatsuo 10443 dest[i] = 0;
244     return dest;
245 maya 3227 }
246    
247 zmatsuo 8858 static void FixLogOption(void)
248 maya 3227 {
249 doda 3887 if (ts.LogBinary) {
250 maya 3227 ts.LogTypePlainText = false;
251     ts.LogTimestamp = false;
252     }
253     }
254    
255 yutakapon 5206
256     // �X���b�h���I�����t�@�C�����N���[�Y
257 zmatsuo 9873 static void CloseFileSync(PFileVar fv)
258 yutakapon 5206 {
259 yutakapon 6489 BOOL ret;
260    
261 zmatsuo 9873 if (fv->FileHandle == INVALID_HANDLE_VALUE) {
262 yutakapon 5206 return;
263 zmatsuo 8901 }
264 yutakapon 5206
265 zmatsuo 9873 if (fv->LogThread != INVALID_HANDLE_VALUE) {
266 yutakapon 5206 // �X���b�h���I������
267 zmatsuo 9873 ret = PostThreadMessage(fv->LogThreadId, WM_QUIT, 0, 0);
268 yutakapon 6489 if (ret != 0) {
269     // �X���b�h�L���[���G���L���[���������������������������s���B
270 zmatsuo 9873 WaitForSingleObject(fv->LogThread, INFINITE);
271 yutakapon 6489 }
272     else {
273 zmatsuo 8852 //DWORD code = GetLastError();
274 yutakapon 6489 }
275 zmatsuo 9873 CloseHandle(fv->LogThread);
276     fv->LogThread = INVALID_HANDLE_VALUE;
277 yutakapon 5206 }
278 zmatsuo 9873 CloseHandle(fv->FileHandle);
279     fv->FileHandle = INVALID_HANDLE_VALUE;
280 yutakapon 5206 }
281    
282     // �x�����������p�X���b�h
283 doda 6435 static unsigned _stdcall DeferredLogWriteThread(void *arg)
284 yutakapon 5206 {
285     MSG msg;
286     PFileVar fv = (PFileVar)arg;
287     PCHAR buf;
288     DWORD buflen;
289 maya 5273 DWORD wrote;
290 yutakapon 5206
291     PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
292    
293 yutakapon 6489 // �X���b�h�L���[���������I�������������X���b�h�����������m�����B
294     if (fv->LogThreadEvent != NULL) {
295     SetEvent(fv->LogThreadEvent);
296     }
297    
298 yutakapon 5206 while (GetMessage(&msg, NULL, 0, 0) > 0) {
299     switch (msg.message) {
300     case WM_DPC_LOGTHREAD_SEND:
301     buf = (PCHAR)msg.wParam;
302     buflen = (DWORD)msg.lParam;
303 zmatsuo 9873 WriteFile(fv->FileHandle, buf, buflen, &wrote, NULL);
304 yutakapon 5206 free(buf); // ����������������
305     break;
306    
307     case WM_QUIT:
308     goto end;
309     break;
310     }
311     }
312    
313     end:
314     _endthreadex(0);
315     return (0);
316     }
317    
318 zmatsuo 8901 // �x�����������p�X���b�h���N�����B
319     // (2013.4.19 yutaka)
320     // DeferredLogWriteThread �X���b�h���N�������A�X���b�h�L���[�����������������O���A
321     // ���O�t�@�C�����N���[�Y(CloseFileSync)���s���������A�G���L���[�����s���A�f�b�h���b�N
322     // �����������������C�������B
323     // �X���b�h�����������s�������A���O�����C�x���g�I�u�W�F�N�g���g�����A�X���b�h�L���[��
324     // ���������������������������������B���O�t���C�x���g�I�u�W�F�N�g���g���������A
325     // �V�X�e��(Windows OS)�������j�[�N�����O�������K�v�������B
326     // (2016.9.23 yutaka)
327     static void StartThread(PFileVar fv)
328     {
329     unsigned tid;
330     fv->LogThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
331     fv->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, fv, 0, &tid);
332     fv->LogThreadId = tid;
333     if (fv->LogThreadEvent != NULL) {
334     WaitForSingleObject(fv->LogThreadEvent, INFINITE);
335     CloseHandle(fv->LogThreadEvent);
336     }
337     }
338    
339     static void OpenLogFile(PFileVar fv)
340     {
341 nmaya 9134 // LogLockExclusive ���L���������������������L���������A
342     // ���������������O�t�@�C���������G�f�B�^���J����������
343 zmatsuo 8901 int dwShareMode = FILE_SHARE_READ;
344     if (!ts.LogLockExclusive) {
345     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
346     }
347 zmatsuo 9873 fv->FileHandle = CreateFileW(fv->FullName, GENERIC_WRITE, dwShareMode, NULL,
348     OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
349 zmatsuo 8901 }
350    
351 zmatsuo 9873 static BOOL LogStart(PFileVar fv, const wchar_t *fname)
352 zmatsuo 8852 {
353 zmatsuo 8901 fv->FullName = _wcsdup(fname);
354 zmatsuo 8852 FixLogOption();
355    
356 doda 3887 if (ts.LogBinary > 0)
357 maya 3227 {
358 zmatsuo 9872 fv->BinLog = TRUE;
359     fv->FileLog = FALSE;
360 maya 3227 if (! CreateBinBuf())
361     {
362     return FALSE;
363     }
364     }
365     else {
366 zmatsuo 9872 fv->BinLog = FALSE;
367     fv->FileLog = TRUE;
368 maya 3227 if (! CreateLogBuf())
369     {
370     return FALSE;
371     }
372     }
373 zmatsuo 8906 cv_LStart = cv_LogPtr;
374     cv_LCount = 0;
375 maya 3227
376 zmatsuo 8901 OpenLogFile(fv);
377 zmatsuo 9871 if (fv->FileHandle == INVALID_HANDLE_VALUE) {
378 zmatsuo 8901 return FALSE;
379     }
380    
381 maya 3227 /* 2007.05.24 Gentaro */
382 zmatsuo 8901 fv->eLineEnd = Line_LineHead;
383 maya 3227 if (ts.Append > 0)
384     {
385 zmatsuo 9871 SetFilePointer(fv->FileHandle, 0, NULL, FILE_END);
386 zmatsuo 8901 /* 2007.05.24 Gentaro
387     If log file already exists,
388     a newline is inserted before the first timestamp.
389     */
390     fv->eLineEnd = Line_FileHead;
391 maya 3227 }
392 zmatsuo 9869
393     // BOM�o��
394     if (ts.Append == 0 && ts.LogBinary == 0 && fv->bom) {
395     // ���L��������(�V�K) && �o�C�i���������� && BOM ���o����
396 zmatsuo 9873 FLogOutputBOM(fv);
397 zmatsuo 8912 }
398 maya 3227
399 yutakapon 5171 // Log rotate configuration
400 zmatsuo 9871 fv->RotateMode = ts.LogRotate;
401     fv->RotateSize = ts.LogRotateSize;
402     fv->RotateStep = ts.LogRotateStep;
403 yutakapon 5162
404 yutakapon 6365 // Log rotate���L���������A�����t�@�C���T�C�Y�����������B
405     // �������t�@�C�������������T�C�Y�����[�e�[�g�������������C���B
406     // (2016.4.9 yutaka)
407 zmatsuo 9871 if (fv->RotateMode != ROTATE_NONE) {
408     DWORD size = GetFileSize(fv->FileHandle, NULL);
409 zmatsuo 8901 if (size == -1) {
410     return FALSE;
411     }
412 zmatsuo 9871 fv->ByteCount = size;
413 yutakapon 6365 }
414 zmatsuo 8901 else {
415 zmatsuo 9871 fv->ByteCount = 0;
416 zmatsuo 8901 }
417 yutakapon 6365
418 zmatsuo 9871 if (! OpenFTDlg_(fv)) {
419 maya 3227 return FALSE;
420     }
421    
422 zmatsuo 9871 fv->IsPause = FALSE;
423     fv->StartTime = GetTickCount();
424 zmatsuo 8899
425 zmatsuo 8901 if (ts.DeferredLogWriteMode) {
426 zmatsuo 9871 StartThread(fv);
427 yutakapon 6489 }
428 yutakapon 5206
429 zmatsuo 9872 if (fv->FileLog) {
430 zmatsuo 8897 cv.Log1Byte = LogPut1;
431     }
432 zmatsuo 9872 if (fv->BinLog) {
433 zmatsuo 8897 cv.Log1Bin = Log1Bin;
434     cv.LogBinSkip = LogBinSkip;
435     }
436    
437 maya 3227 return TRUE;
438     }
439    
440 zmatsuo 8897 /**
441 zmatsuo 8908 * �����o�b�t�@�������f�[�^�����������O�������o��
442     * (2013.9.29 yutaka)
443     *
444     * TODO
445     * 1�s������
446     */
447     void FLogOutputAllBuffer(void)
448     {
449 zmatsuo 9873 PFileVar fv = LogVar;
450 zmatsuo 8909 DWORD ofs;
451 zmatsuo 8908 int size;
452     wchar_t buf[512];
453     for (ofs = 0 ; ; ofs++ ) {
454     // 1�����s�����������B���������������A�G�X�P�[�v�V�[�P���X�������������B
455     size = BuffGetAnyLineDataW(ofs, buf, _countof(buf));
456     if (size == -1)
457     break;
458    
459     OutputStr(buf);
460     OutputStr(L"\r\n");
461 zmatsuo 9873 LogToFile(fv);
462 zmatsuo 8908 }
463     }
464    
465     /**
466 zmatsuo 8897 * ���O��1byte��������
467     * �o�b�t�@��������������
468     * ���������������� LogToFile() ���s������
469     */
470 maya 3227 void LogPut1(BYTE b)
471     {
472 zmatsuo 9872 PFileVar fv = LogVar;
473    
474 zmatsuo 8906 cv_LogBuf[cv_LogPtr] = b;
475     cv_LogPtr++;
476     if (cv_LogPtr>=InBuffSize)
477     cv_LogPtr = cv_LogPtr-InBuffSize;
478 maya 3227
479 zmatsuo 9872 if (fv->FileLog)
480 maya 3227 {
481 zmatsuo 8906 if (cv_LCount>=InBuffSize)
482 maya 3227 {
483 zmatsuo 8906 cv_LCount = InBuffSize;
484     cv_LStart = cv_LogPtr;
485 maya 3227 }
486     else
487 zmatsuo 8906 cv_LCount++;
488 maya 3227 }
489     else
490 zmatsuo 8906 cv_LCount = 0;
491 maya 3227 }
492    
493     static BOOL Get1(PCHAR Buf, int *Start, int *Count, PBYTE b)
494     {
495     if (*Count<=0) return FALSE;
496     *b = Buf[*Start];
497     (*Start)++;
498     if (*Start>=InBuffSize)
499     *Start = *Start-InBuffSize;
500     (*Count)--;
501     return TRUE;
502     }
503    
504    
505    
506     static CRITICAL_SECTION g_filelog_lock; /* ���b�N�p���� */
507    
508     void logfile_lock_initialize(void)
509     {
510     InitializeCriticalSection(&g_filelog_lock);
511     }
512    
513     static inline void logfile_lock(void)
514     {
515     EnterCriticalSection(&g_filelog_lock);
516     }
517    
518     static inline void logfile_unlock(void)
519     {
520     LeaveCriticalSection(&g_filelog_lock);
521     }
522    
523 yutakapon 5162 // ���O�����[�e�[�g�����B
524     // (2013.3.21 yutaka)
525 zmatsuo 9873 static void LogRotate(PFileVar fv)
526 yutakapon 5162 {
527 yutakapon 5165 int loopmax = 10000; // XXX
528     int i, k;
529 yutakapon 5162
530 zmatsuo 9873 if (fv->RotateMode == ROTATE_NONE)
531 yutakapon 5162 return;
532    
533 zmatsuo 9873 if (fv->RotateMode == ROTATE_SIZE) {
534     if (fv->ByteCount <= fv->RotateSize)
535 yutakapon 5162 return;
536 zmatsuo 9873 //OutputDebugPrintf("%s: mode %d size %ld\n", __FUNCTION__, fv->RotateMode, fv->ByteCount);
537 yutakapon 5162 } else {
538     return;
539     }
540    
541     logfile_lock();
542     // ���O�T�C�Y���������������B
543 zmatsuo 9873 fv->ByteCount = 0;
544 yutakapon 5162
545     // �������������t�@�C�����N���[�Y�����A�������t�@�C�����I�[�v�������B
546 zmatsuo 9873 CloseFileSync(fv);
547 yutakapon 5162
548 yutakapon 5165 // �������[�e�[�V�������X�e�b�v�����w����������
549 zmatsuo 9873 if (fv->RotateStep > 0)
550     loopmax = fv->RotateStep;
551 yutakapon 5165
552     for (i = 1 ; i <= loopmax ; i++) {
553 zmatsuo 8899 wchar_t *filename;
554 zmatsuo 9873 aswprintf(&filename, L"%s.%d", fv->FullName, i);
555 zmatsuo 9324 DWORD attr = GetFileAttributesW(filename);
556 zmatsuo 8899 free(filename);
557 zmatsuo 8901 if (attr == INVALID_FILE_ATTRIBUTES)
558 yutakapon 5162 break;
559     }
560 yutakapon 5165 if (i > loopmax) {
561     // �������������������������A�������t�@�C�������p�������B
562     i = loopmax;
563 yutakapon 5162 }
564    
565     // ���t�@�C�������l�[���B
566 yutakapon 5165 for (k = i-1 ; k >= 0 ; k--) {
567 zmatsuo 8899 wchar_t *oldfile;
568 yutakapon 5165 if (k == 0)
569 zmatsuo 9873 oldfile = _wcsdup(fv->FullName);
570 yutakapon 5165 else
571 zmatsuo 9873 aswprintf(&oldfile, L"%s.%d", fv->FullName, k);
572 zmatsuo 8899 wchar_t *newfile;
573 zmatsuo 9873 aswprintf(&newfile, L"%s.%d", fv->FullName, k+1);
574 zmatsuo 9324 DeleteFileW(newfile);
575     if (MoveFileW(oldfile, newfile) == 0) {
576 yutakapon 5165 OutputDebugPrintf("%s: rename %d\n", __FUNCTION__, errno);
577     }
578 zmatsuo 8899 free(oldfile);
579     free(newfile);
580 yutakapon 5165 }
581 yutakapon 5162
582     // ���I�[�v��
583 zmatsuo 9873 OpenLogFile(fv);
584     if (fv->bom) {
585     FLogOutputBOM(fv);
586 zmatsuo 8912 }
587 zmatsuo 8901 if (ts.DeferredLogWriteMode) {
588 zmatsuo 9873 StartThread(fv);
589 yutakapon 5162 }
590    
591     logfile_unlock();
592     }
593    
594 zmatsuo 9873 static wchar_t *TimeStampStr(PFileVar fv)
595 zmatsuo 8909 {
596     char *strtime = NULL;
597     switch (ts.LogTimestampType) {
598     case TIMESTAMP_LOCAL:
599     default:
600     strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
601     break;
602     case TIMESTAMP_UTC:
603     strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
604     break;
605     case TIMESTAMP_ELAPSED_LOGSTART:
606 zmatsuo 9873 strtime = strelapsed(fv->StartTime);
607 zmatsuo 8909 break;
608     case TIMESTAMP_ELAPSED_CONNECTED:
609     strtime = strelapsed(cv.ConnectedTime);
610     break;
611     }
612    
613     char tmp[128];
614     tmp[0] = 0;
615     strncat_s(tmp, sizeof(tmp), "[", _TRUNCATE);
616     strncat_s(tmp, sizeof(tmp), strtime, _TRUNCATE);
617     strncat_s(tmp, sizeof(tmp), "] ", _TRUNCATE);
618 zmatsuo 10958 free(strtime);
619 zmatsuo 8909
620 zmatsuo 8910 return ToWcharA(tmp);
621 zmatsuo 8909 }
622    
623 zmatsuo 8897 /**
624     * �o�b�t�@�������O���t�@�C������������
625     */
626 zmatsuo 9873 static void LogToFile(PFileVar fv)
627 maya 3227 {
628     PCHAR Buf;
629     int Start, Count;
630     BYTE b;
631    
632 zmatsuo 9872 if (fv->FileLog)
633 maya 3227 {
634 zmatsuo 8906 Buf = cv_LogBuf;
635     Start = cv_LStart;
636     Count = cv_LCount;
637 maya 3227 }
638 zmatsuo 9872 else if (fv->BinLog)
639 maya 3227 {
640 zmatsuo 8906 Buf = cv_BinBuf;
641     Start = cv_BStart;
642     Count = cv_BCount;
643 maya 3227 }
644     else
645     return;
646    
647     if (Buf==NULL) return;
648     if (Count==0) return;
649    
650     // ���b�N������(2004.8.6 yutaka)
651     logfile_lock();
652    
653 zmatsuo 8909 // ���������f�[�^����������
654     DWORD WriteBufMax = 8192;
655     DWORD WriteBufLen = 0;
656     PCHAR WriteBuf = (PCHAR)malloc(WriteBufMax);
657     while (Get1(Buf,&Start,&Count,&b)) {
658 zmatsuo 9103 if (FLogIsPause() || ProtoGetProtoFlag()) {
659 zmatsuo 8909 continue;
660     }
661 doda 6947
662 zmatsuo 8909 if (WriteBufLen >= (WriteBufMax*4/5)) {
663     WriteBufMax *= 2;
664     WriteBuf = (PCHAR)realloc(WriteBuf, WriteBufMax);
665     }
666 doda 6947
667 zmatsuo 8909 WriteBuf[WriteBufLen++] = b;
668 yutakapon 5206
669 zmatsuo 9873 (fv->ByteCount)++;
670 zmatsuo 8909 }
671 yutakapon 5206
672 zmatsuo 8909 // ��������
673     if (WriteBufLen > 0) {
674     if (ts.DeferredLogWriteMode) {
675 zmatsuo 9873 PostThreadMessage(fv->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)WriteBuf, WriteBufLen);
676 yutakapon 5206 }
677 zmatsuo 8909 else {
678     DWORD wrote;
679 zmatsuo 9873 WriteFile(fv->FileHandle, WriteBuf, WriteBufLen, &wrote, NULL);
680 zmatsuo 8909 free(WriteBuf);
681     }
682 maya 3227 }
683    
684     logfile_unlock();
685    
686 zmatsuo 9872 if (fv->FileLog)
687 maya 3227 {
688 zmatsuo 8906 cv_LStart = Start;
689     cv_LCount = Count;
690 maya 3227 }
691     else {
692 zmatsuo 8906 cv_BStart = Start;
693     cv_BCount = Count;
694 maya 3227 }
695 zmatsuo 9103 if (FLogIsPause() || ProtoGetProtoFlag()) return;
696 zmatsuo 9873 fv->FLogDlg->RefreshNum(fv->StartTime, fv->FileSize, fv->ByteCount);
697 yutakapon 5162
698 zmatsuo 8896
699 yutakapon 5162 // ���O�E���[�e�[�g
700 zmatsuo 9873 LogRotate(fv);
701 maya 3227 }
702    
703 zmatsuo 8897 static BOOL CreateLogBuf(void)
704 maya 3227 {
705 zmatsuo 8906 if (cv_LogBuf==NULL)
706 maya 3227 {
707 zmatsuo 8906 cv_LogBuf = (char *)malloc(InBuffSize);
708     cv_LogPtr = 0;
709     cv_LStart = 0;
710     cv_LCount = 0;
711 maya 3227 }
712 zmatsuo 8906 return (cv_LogBuf!=NULL);
713 maya 3227 }
714    
715 zmatsuo 8897 static void FreeLogBuf(void)
716 maya 3227 {
717 zmatsuo 8906 free(cv_LogBuf);
718     cv_LogBuf = NULL;
719     cv_LogPtr = 0;
720     cv_LStart = 0;
721     cv_LCount = 0;
722 maya 3227 }
723    
724 zmatsuo 8897 static BOOL CreateBinBuf(void)
725 maya 3227 {
726 zmatsuo 8906 if (cv_BinBuf==NULL)
727 maya 3227 {
728 zmatsuo 8906 cv_BinBuf = (PCHAR)malloc(InBuffSize);
729     cv_BinPtr = 0;
730     cv_BStart = 0;
731     cv_BCount = 0;
732 maya 3227 }
733 zmatsuo 8906 return (cv_BinBuf!=NULL);
734 maya 3227 }
735    
736 zmatsuo 8897 static void FreeBinBuf(void)
737 maya 3227 {
738 zmatsuo 8906 free(cv_BinBuf);
739     cv_BinBuf = NULL;
740     cv_BinPtr = 0;
741     cv_BStart = 0;
742     cv_BCount = 0;
743 maya 3227 }
744    
745 zmatsuo 9873 static void FileTransEnd_(PFileVar fv)
746 maya 3227 {
747 zmatsuo 9872 fv->FileLog = FALSE;
748     fv->BinLog = FALSE;
749 zmatsuo 8897 cv.Log1Byte = NULL;
750     cv.Log1Bin = NULL;
751     cv.LogBinSkip = NULL;
752 zmatsuo 9873 PFileTransDlg FLogDlg = fv->FLogDlg;
753 zmatsuo 8901 if (FLogDlg != NULL) {
754 zmatsuo 8897 FLogDlg->DestroyWindow();
755     FLogDlg = NULL;
756 zmatsuo 9873 fv->FLogDlg = NULL;
757 maya 3227 }
758 zmatsuo 9873 CloseFileSync(fv);
759 zmatsuo 8897 FreeLogBuf();
760     FreeBinBuf();
761 zmatsuo 9873 free(fv->FullName);
762     fv->FullName = NULL;
763     free(fv);
764    
765 zmatsuo 8900 LogVar = NULL;
766 maya 3227 }
767    
768 zmatsuo 8857 /**
769     * ���O���|�[�Y����
770     */
771     void FLogPause(BOOL Pause)
772 maya 3227 {
773 zmatsuo 9873 PFileVar fv = LogVar;
774     if (fv == NULL) {
775 zmatsuo 8899 return;
776     }
777 zmatsuo 9873 fv->IsPause = Pause;
778     fv->FLogDlg->ChangeButton(Pause);
779 maya 3227 }
780    
781 zmatsuo 8857 /**
782 zmatsuo 8852 * ���O���[�e�[�g������
783     * ���O���T�C�Y��<size>�o�C�g���������������A���[�e�[�V��������������������
784     */
785 zmatsuo 8858 void FLogRotateSize(size_t size)
786 zmatsuo 8852 {
787 zmatsuo 9873 PFileVar fv = LogVar;
788     if (fv == NULL) {
789 zmatsuo 8852 return;
790     }
791 zmatsuo 9873 fv->RotateMode = ROTATE_SIZE;
792     fv->RotateSize = (LONG)size;
793 zmatsuo 8852 }
794    
795     /**
796     * ���O���[�e�[�g������
797     * ���O�t�@�C������������������
798     */
799 zmatsuo 8858 void FLogRotateRotate(int step)
800 zmatsuo 8852 {
801 zmatsuo 9873 PFileVar fv = LogVar;
802     if (fv == NULL) {
803 zmatsuo 8852 return;
804     }
805 zmatsuo 9873 fv->RotateStep = step;
806 zmatsuo 8852 }
807    
808     /**
809     * ���O���[�e�[�g������
810     * ���[�e�[�V���������~
811     */
812 zmatsuo 8858 void FLogRotateHalt(void)
813 zmatsuo 8852 {
814 zmatsuo 9873 PFileVar fv = LogVar;
815     if (fv == NULL) {
816 zmatsuo 8852 return;
817     }
818 zmatsuo 9873 fv->RotateMode = ROTATE_NONE;
819     fv->RotateSize = 0;
820     fv->RotateStep = 0;
821 zmatsuo 8852 }
822    
823 zmatsuo 9854 static INT_PTR CALLBACK OnCommentDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM)
824 zmatsuo 8852 {
825     static const DlgTextInfo TextInfos[] = {
826     { 0, "DLG_COMMENT_TITLE" },
827     { IDOK, "BTN_OK" }
828     };
829    
830     switch (msg) {
831     case WM_INITDIALOG:
832     // �G�f�B�b�g�R���g���[�����t�H�[�J�X��������
833     SetFocus(GetDlgItem(hDlgWnd, IDC_EDIT_COMMENT));
834 zmatsuo 9350 SetDlgTextsW(hDlgWnd, TextInfos, _countof(TextInfos), ts.UILanguageFileW);
835 zmatsuo 8852 return FALSE;
836    
837     case WM_COMMAND:
838     switch (LOWORD(wp)) {
839 zmatsuo 8901 case IDOK: {
840 zmatsuo 9324 size_t len = SendDlgItemMessageW(hDlgWnd, IDC_EDIT_COMMENT, WM_GETTEXTLENGTH, 0, 0);
841 zmatsuo 8907 len += 1;
842     wchar_t *buf = (wchar_t *)malloc(len * sizeof(wchar_t));
843 zmatsuo 9324 GetDlgItemTextW(hDlgWnd, IDC_EDIT_COMMENT, buf, (int)len);
844 zmatsuo 8905 FLogWriteStr(buf);
845     FLogWriteStr(L"\n"); // TODO ���s�R�[�h
846     free(buf);
847 zmatsuo 8852 TTEndDialog(hDlgWnd, IDOK);
848     break;
849 zmatsuo 8901 }
850 zmatsuo 8852 default:
851     return FALSE;
852     }
853     break;
854 zmatsuo 8907
855 zmatsuo 8852 case WM_CLOSE:
856     TTEndDialog(hDlgWnd, 0);
857     return TRUE;
858    
859     default:
860     return FALSE;
861     }
862     return TRUE;
863     }
864    
865 zmatsuo 8905 /**
866     * ���O�t�@�C�����R�����g���������� (2004.8.6 yutaka)
867     */
868 zmatsuo 8858 void FLogAddCommentDlg(HINSTANCE hInst, HWND hWnd)
869 zmatsuo 8852 {
870 zmatsuo 9873 PFileVar fv = LogVar;
871     if (fv == NULL) {
872 zmatsuo 8905 return;
873     }
874 zmatsuo 8852 TTDialogBox(hInst, MAKEINTRESOURCE(IDD_COMMENT_DIALOG),
875 zmatsuo 9854 hWnd, OnCommentDlgProc);
876 zmatsuo 8852 }
877    
878 zmatsuo 8858 void FLogClose(void)
879 zmatsuo 8852 {
880 zmatsuo 9873 PFileVar fv = LogVar;
881     if (fv == NULL) {
882 zmatsuo 8897 return;
883     }
884    
885 zmatsuo 9873 FileTransEnd_(fv);
886 zmatsuo 8852 }
887    
888 zmatsuo 8897 /**
889     * ���O���I�[�v������
890     * @param[in] fname ���O�t�@�C����, CreateFile()���n������
891     *
892     * ���O�t�@�C������strftime���W�J�������s���������B
893     * FLogGetLogFilename() �� FLogOpenDialog() ��
894     * �t�@�C�����������������B
895     */
896 zmatsuo 8912 BOOL FLogOpen(const wchar_t *fname, LogCode_t code, BOOL bom)
897 zmatsuo 8852 {
898 zmatsuo 8894 if (LogVar != NULL) {
899 zmatsuo 8852 return FALSE;
900     }
901    
902 zmatsuo 8897 //
903 zmatsuo 9873 PFileVar fv = (PFileVar)malloc(sizeof(*fv));
904 zmatsuo 8897 if (fv == NULL) {
905     return FALSE;
906     }
907     LogVar = fv;
908     memset(fv, 0, sizeof(TFileVar));
909 zmatsuo 8901 fv->FileHandle = INVALID_HANDLE_VALUE;
910     fv->LogThread = INVALID_HANDLE_VALUE;
911     fv->eLineEnd = Line_LineHead;
912 zmatsuo 8897
913 zmatsuo 8912 fv->log_code = code;
914     fv->bom = bom;
915 zmatsuo 9873 BOOL ret = LogStart(fv, fname);
916 zmatsuo 8901 if (ret == FALSE) {
917 zmatsuo 9873 FileTransEnd_(fv);
918 zmatsuo 8901 }
919 zmatsuo 8897
920 zmatsuo 8852 return ret;
921     }
922    
923 zmatsuo 8858 BOOL FLogIsOpend(void)
924 zmatsuo 8852 {
925     return LogVar != NULL;
926     }
927    
928 zmatsuo 8904 BOOL FLogIsOpendText(void)
929     {
930 zmatsuo 9872 return LogVar != NULL && LogVar->FileLog;
931 zmatsuo 8904 }
932    
933     BOOL FLogIsOpendBin(void)
934     {
935 zmatsuo 9872 return LogVar != NULL && LogVar->BinLog;
936 zmatsuo 8904 }
937    
938 zmatsuo 8905 void FLogWriteStr(const wchar_t *str)
939 zmatsuo 8852 {
940 zmatsuo 8905 if (LogVar != NULL) {
941 zmatsuo 8907 OutputStr(str);
942 zmatsuo 8852 }
943     }
944    
945 zmatsuo 8858 void FLogInfo(char *param_ptr, size_t param_len)
946 zmatsuo 8852 {
947 zmatsuo 9873 PFileVar fv = LogVar;
948     if (fv) {
949 zmatsuo 8852 param_ptr[0] = '0'
950     + (ts.LogBinary != 0)
951     + ((ts.Append != 0) << 1)
952     + ((ts.LogTypePlainText != 0) << 2)
953     + ((ts.LogTimestamp != 0) << 3)
954     + ((ts.LogHideDialog != 0) << 4);
955 zmatsuo 9873 char *filenameU8 = ToU8W(fv->FullName);
956 zmatsuo 8899 strncpy_s(param_ptr + 1, param_len - 1, filenameU8, _TRUNCATE);
957     free(filenameU8);
958 zmatsuo 8852 }
959     else {
960     param_ptr[0] = '0' - 1;
961     param_ptr[1] = 0;
962     }
963     }
964    
965     /**
966     * ���������O�t�@�C����������
967     */
968 zmatsuo 8899 const wchar_t *FLogGetFilename(void)
969 zmatsuo 8852 {
970     if (LogVar == NULL) {
971     return NULL;
972     }
973     return LogVar->FullName;
974     }
975    
976     /**
977 zmatsuo 10444 * ���O�t�@�C�����p���C�����s��,�t�@�C������������
978     * - strftime() ���������t�W�J
979     * - �������������O�t�@�C���t�H���_������
980     * - �z�X�g��,�|�[�g�����W�J
981     *
982     * @param filename �t�@�C����(�p�X����������)
983     * @return �C�������t�@�C����
984     */
985     wchar_t *FLogGetLogFilenameBase(const wchar_t *filename)
986     {
987     // �t�@�C�������������o
988 zmatsuo 10464 const wchar_t *last_path_sep = wcsrchr(filename, L'\\');
989     wchar_t *format;
990     if (last_path_sep == NULL) {
991 zmatsuo 10468 format = _wcsdup(filename);
992 zmatsuo 10444 }
993 zmatsuo 10464 else {
994 zmatsuo 10468 format = _wcsdup(last_path_sep + 1);
995 zmatsuo 10464 }
996 zmatsuo 10444
997     // strftime ���g�p������������������
998     deleteInvalidStrftimeCharW(format);
999    
1000 zmatsuo 10464 // ����������0��������?
1001     if (format[0] == 0) {
1002     free(format);
1003 zmatsuo 10468 return _wcsdup(L"");
1004 zmatsuo 10464 }
1005    
1006 zmatsuo 10444 // ��������������
1007     time_t time_local;
1008     time(&time_local);
1009     struct tm tm_local;
1010     localtime_s(&tm_local, &time_local);
1011    
1012     // strftime()������
1013 zmatsuo 10464 // ���������������g��
1014     size_t len = 32;
1015     wchar_t *formated = NULL;
1016     while (1) {
1017     wchar_t *formated_realloc = (wchar_t *)realloc(formated, sizeof(wchar_t) * len);
1018     if (formated_realloc == NULL) {
1019     free(format);
1020     free(formated);
1021 zmatsuo 10468 return _wcsdup(L"");
1022 zmatsuo 10464 }
1023     formated = formated_realloc;
1024     size_t r = wcsftime(formated, len, format, &tm_local);
1025     if (r != 0) {
1026     // �t�H�[�}�b�g������
1027     break;
1028     }
1029     len *= 2;
1030 zmatsuo 10444 }
1031     free(format);
1032    
1033     // �z�X�g������
1034     wchar_t *host = ConvertLognameW(&cv, formated);
1035     free(formated);
1036    
1037     // �t�@�C�������g�p���������������u��
1038     //wchar_t *replaced = replaceInvalidFileNameCharW(host, 0); // ����
1039     wchar_t *replaced = replaceInvalidFileNameCharW(host, L'_');
1040     free(host);
1041    
1042     return replaced;
1043     }
1044    
1045     /**
1046 zmatsuo 8852 * ���O�t�@�C����������
1047     * ���O�t�@�C�����p���C�����s��
1048     * - strftime() ���������t�W�J
1049     * - �������������O�t�@�C���t�H���_������
1050     * - �z�X�g��,�|�[�g�����W�J
1051     *
1052     * @param[in] log_filename �t�@�C����(����/��������������ok)
1053     * NULL�������f�t�H���g�t�@�C����������
1054     * strftime�`��ok
1055     * @return �t���p�X�t�@�C����
1056     * �s�v���������� free() ��������
1057     */
1058 zmatsuo 8899 wchar_t *FLogGetLogFilename(const wchar_t *log_filename)
1059 zmatsuo 8852 {
1060 zmatsuo 10444 wchar_t *dir;
1061     wchar_t *fname;
1062 zmatsuo 8852 if (log_filename == NULL) {
1063 zmatsuo 10468 dir = _wcsdup(ts.LogDefaultPathW);
1064     fname = _wcsdup(ts.LogDefaultNameW);
1065 zmatsuo 10444 } else if (!IsRelativePathW(log_filename)) {
1066     // �����p�X������������
1067     dir = ExtractDirNameW(log_filename);
1068     fname = ExtractFileNameW(log_filename);
1069 zmatsuo 8852 }
1070     else {
1071 zmatsuo 10468 dir = _wcsdup(ts.LogDefaultPathW);
1072     fname = _wcsdup(log_filename);
1073 zmatsuo 8852 }
1074    
1075 zmatsuo 10444 wchar_t *formated = FLogGetLogFilenameBase(fname);
1076     free(fname);
1077 zmatsuo 8852
1078 zmatsuo 10444 // �A������
1079     wchar_t *logfull = NULL;
1080     awcscats(&logfull, dir, L"\\", formated, NULL);
1081 zmatsuo 10606 free(formated);
1082 zmatsuo 10444 free(dir);
1083    
1084     // ���K��
1085     wchar_t *normal;
1086     hGetFullPathNameW(logfull, &normal, NULL);
1087     free(logfull);
1088    
1089     return normal;
1090 zmatsuo 8852 }
1091 zmatsuo 8857
1092     BOOL FLogIsPause()
1093     {
1094 zmatsuo 8900 if (LogVar == NULL) {
1095     return FALSE;
1096     }
1097     return LogVar->IsPause;
1098 zmatsuo 8857 }
1099    
1100     void FLogWindow(int nCmdShow)
1101     {
1102 zmatsuo 8900 if (LogVar == NULL) {
1103     return;
1104     }
1105 zmatsuo 8857
1106 zmatsuo 8901 HWND HWndLog = LogVar->FLogDlg->m_hWnd;
1107 zmatsuo 8857 ShowWindow(HWndLog, nCmdShow);
1108     if (nCmdShow == SW_RESTORE) {
1109     // �g���X�^�C�� WS_EX_NOACTIVATE ��������������
1110     SetForegroundWindow(HWndLog);
1111     }
1112     }
1113    
1114     void FLogShowDlg(void)
1115     {
1116 zmatsuo 8900 if (LogVar == NULL) {
1117     return;
1118     }
1119 zmatsuo 8901 HWND HWndLog = LogVar->FLogDlg->m_hWnd;
1120     ShowWindow(HWndLog, SW_SHOWNORMAL);
1121     SetForegroundWindow(HWndLog);
1122 zmatsuo 8857 }
1123 zmatsuo 8897
1124     /**
1125     * ���O��1byte��������
1126     * LogPut1() ������?
1127     */
1128     //void Log1Bin(PComVar cv, BYTE b)
1129     static void Log1Bin(BYTE b)
1130     {
1131 zmatsuo 9103 if (LogVar->IsPause || ProtoGetProtoFlag()) {
1132 zmatsuo 8897 return;
1133     }
1134 zmatsuo 8906 if (cv_BinSkip > 0) {
1135     cv_BinSkip--;
1136 zmatsuo 8897 return;
1137     }
1138 zmatsuo 8906 cv_BinBuf[cv_BinPtr] = b;
1139     cv_BinPtr++;
1140     if (cv_BinPtr>=InBuffSize) {
1141     cv_BinPtr = cv_BinPtr-InBuffSize;
1142 zmatsuo 8897 }
1143 zmatsuo 8906 if (cv_BCount>=InBuffSize) {
1144     cv_BCount = InBuffSize;
1145     cv_BStart = cv_BinPtr;
1146 zmatsuo 8897 }
1147     else {
1148 zmatsuo 8906 cv_BCount++;
1149 zmatsuo 8897 }
1150     }
1151    
1152     static void LogBinSkip(int add)
1153     {
1154 zmatsuo 8906 if (cv_BinBuf != NULL) {
1155     cv_BinSkip += add;
1156 zmatsuo 8897 }
1157     }
1158    
1159     /**
1160     * ���O�o�b�t�@���������������f�[�^���o�C�g��������
1161     */
1162     int FLogGetCount(void)
1163     {
1164 zmatsuo 9872 PFileVar fv = LogVar;
1165     if (fv == NULL) {
1166     return 0;
1167     }
1168     if (fv->FileLog) {
1169 zmatsuo 8906 return cv_LCount;
1170 zmatsuo 8897 }
1171 zmatsuo 9872 if (fv->BinLog) {
1172 zmatsuo 8906 return cv_BCount;
1173 zmatsuo 8897 }
1174     return 0;
1175     }
1176    
1177     /**
1178 zmatsuo 8906 * ���O�o�b�t�@�������o�C�g��������
1179     */
1180     int FLogGetFreeCount(void)
1181     {
1182 zmatsuo 9872 PFileVar fv = LogVar;
1183     if (fv == NULL) {
1184     return 0;
1185     }
1186     if (fv->FileLog) {
1187 zmatsuo 8906 return InBuffSize - cv_LCount;
1188     }
1189 zmatsuo 9872 if (fv->BinLog) {
1190 zmatsuo 8906 return InBuffSize - cv_BCount;
1191     }
1192     return 0;
1193     }
1194    
1195     /**
1196 zmatsuo 8897 * �o�b�t�@�������O���t�@�C������������
1197     */
1198     void FLogWriteFile(void)
1199     {
1200 zmatsuo 9872 PFileVar fv = LogVar;
1201     if (fv == NULL) {
1202     return;
1203     }
1204 zmatsuo 8906 if (cv_LogBuf!=NULL)
1205 zmatsuo 8897 {
1206 zmatsuo 9872 if (fv->FileLog) {
1207 zmatsuo 9873 LogToFile(fv);
1208 zmatsuo 8897 }
1209     }
1210    
1211 zmatsuo 8906 if (cv_BinBuf!=NULL)
1212 zmatsuo 8897 {
1213 zmatsuo 9872 if (fv->BinLog) {
1214 zmatsuo 9873 LogToFile(fv);
1215 zmatsuo 8897 }
1216     }
1217     }
1218 zmatsuo 8904
1219     void FLogPutUTF32(unsigned int u32)
1220     {
1221     PFileVar fv = LogVar;
1222 zmatsuo 8906 BOOL log_available = (cv_LogBuf != 0);
1223 zmatsuo 8904
1224     if (!log_available) {
1225 zmatsuo 8905 // ���O�����o��������
1226 zmatsuo 8904 return;
1227     }
1228    
1229 zmatsuo 8912 // �s����?(���s���o����������)
1230 zmatsuo 8910 if (ts.LogTimestamp && fv->eLineEnd) {
1231 zmatsuo 8912 // �^�C���X�^���v���o��
1232 zmatsuo 8910 fv->eLineEnd = Line_Other; /* clear endmark*/
1233 zmatsuo 9873 wchar_t* strtime = TimeStampStr(fv);
1234 zmatsuo 8910 FLogWriteStr(strtime);
1235     free(strtime);
1236     }
1237    
1238 zmatsuo 8904 switch(fv->log_code) {
1239 zmatsuo 8912 case LOG_UTF8: {
1240 zmatsuo 8904 // UTF-8
1241     char u8_buf[4];
1242     size_t u8_len = UTF32ToUTF8(u32, u8_buf, _countof(u8_buf));
1243 zmatsuo 9854 for (size_t i = 0; i < u8_len; i++) {
1244 zmatsuo 8904 BYTE b = u8_buf[i];
1245     LogPut1(b);
1246     }
1247     break;
1248     }
1249 zmatsuo 8912 case LOG_UTF16LE:
1250     case LOG_UTF16BE: {
1251 zmatsuo 8904 // UTF-16
1252     wchar_t u16[2];
1253     size_t u16_len = UTF32ToUTF16(u32, u16, _countof(u16));
1254 zmatsuo 9854 for (size_t i = 0; i < u16_len; i++) {
1255 zmatsuo 8912 if (fv->log_code == LOG_UTF16LE) {
1256 zmatsuo 8904 // UTF-16LE
1257     LogPut1(u16[i] & 0xff);
1258     LogPut1((u16[i] >> 8) & 0xff);
1259     }
1260     else {
1261     // UTF-16BE
1262     LogPut1((u16[i] >> 8) & 0xff);
1263     LogPut1(u16[i] & 0xff);
1264     }
1265     }
1266     }
1267     }
1268 zmatsuo 8910
1269     if (u32 == 0x0a) {
1270     fv->eLineEnd = Line_LineHead; /* set endmark*/
1271     }
1272 zmatsuo 8904 }
1273    
1274 zmatsuo 9873 static void FLogOutputBOM(PFileVar fv)
1275 zmatsuo 8904 {
1276 zmatsuo 8910 DWORD wrote;
1277 zmatsuo 8904
1278     switch(fv->log_code) {
1279 zmatsuo 8910 case 0: {
1280 zmatsuo 8904 // UTF-8
1281 zmatsuo 8910 const char *bom = "\xef\xbb\xbf";
1282 zmatsuo 9871 WriteFile(fv->FileHandle, bom, 3, &wrote, NULL);
1283     fv->ByteCount += 3;
1284 zmatsuo 8904 break;
1285 zmatsuo 8910 }
1286     case 1: {
1287 zmatsuo 8904 // UTF-16LE
1288 zmatsuo 8910 const char *bom = "\xff\xfe";
1289 zmatsuo 9871 WriteFile(fv->FileHandle, bom, 2, &wrote, NULL);
1290     fv->ByteCount += 2;
1291 zmatsuo 8904 break;
1292 zmatsuo 8910 }
1293     case 2: {
1294 zmatsuo 8904 // UTF-16BE
1295 zmatsuo 8910 const char *bom = "\xfe\xff";
1296 zmatsuo 9871 WriteFile(fv->FileHandle, bom, 2, &wrote, NULL);
1297     fv->ByteCount += 2;
1298 zmatsuo 8904 break;
1299 zmatsuo 8910 }
1300 zmatsuo 8904 default:
1301     break;
1302     }
1303     }
1304    
1305 zmatsuo 8907 static void OutputStr(const wchar_t *str)
1306     {
1307     size_t len;
1308    
1309     assert(str != NULL);
1310    
1311     len = wcslen(str);
1312     while(*str != 0) {
1313     unsigned int u32;
1314     size_t u16_len = UTF16ToUTF32(str, len, &u32);
1315     switch (u16_len) {
1316     case 0:
1317     default:
1318     // ������������
1319     str++;
1320     len--;
1321     break;
1322     case 1:
1323     case 2: {
1324     FLogPutUTF32(u32);
1325     str += u16_len;
1326     len -= u16_len;
1327     break;
1328     }
1329     }
1330     }
1331     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26