Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/teraterm/teraterm/filesys_log.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8896 - (show annotations) (download) (as text)
Tue Aug 18 15:27:45 2020 UTC (3 years, 7 months ago) by zmatsuo
File MIME type: text/x-c++src
File size: 41204 byte(s)
ログ出力内で、グローバルに定義されている構造体を使用しないよう修正

- TFileVar#ttftypes.h を使用しないよう修正
  - ローカル構造体に切り替え
  - define で名前の付替えを行っている
- TFileVar#ttftypes.h の未使用メンバを削除
1 /*
2 * (C) 2020 TeraTerm Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 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 *
17 * 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 */
28
29 /* TERATERM.EXE, file transfer routines */
30 #include <stdio.h>
31 #include <io.h>
32 #include <process.h>
33 #include <windows.h>
34 #include <htmlhelp.h>
35 #include <assert.h>
36
37 #include "teraterm.h"
38 #include "tttypes.h"
39 #include "ttftypes.h"
40 #include "ftdlg.h"
41 #include "ttwinman.h"
42 #include "commlib.h"
43 #include "ttcommon.h"
44 #include "ttlib.h"
45 #include "dlglib.h"
46 #include "vtterm.h"
47 #include "ftlib.h"
48 #include "buffer.h"
49 #include "helpid.h"
50 #include "layer_for_unicode.h"
51 #include "layer_for_unicode_crt.h"
52 #include "codeconv.h"
53
54 #include "filesys_log_res.h"
55 #include "filesys.h"
56
57 typedef struct {
58 HWND HMainWin;
59 HWND HWin;
60 WORD OpId;
61 char DlgCaption[40];
62
63 char FullName[MAX_PATH];
64 int DirLen;
65
66 int NumFname, FNCount;
67 HANDLE FnStrMemHandle;
68 PCHAR FnStrMem;
69 int FnPtr;
70
71 BOOL FileOpen;
72 HANDLE FileHandle;
73 LONG FileSize, ByteCount;
74 BOOL OverWrite;
75
76 BOOL LogFlag;
77 HANDLE LogFile;
78 WORD LogState;
79 WORD LogCount;
80
81 BOOL Success;
82 BOOL NoMsg;
83
84 char LogDefaultPath[MAX_PATH];
85 BOOL HideDialog;
86
87 BYTE LogLineBuf[16];
88 int FlushLogLineBuf;
89
90 int ProgStat;
91
92 DWORD StartTime;
93
94 // log rotate
95 int RotateMode; // enum rotate_mode RotateMode;
96 LONG RotateSize;
97 int RotateStep;
98
99 HANDLE LogThread;
100 DWORD LogThreadId;
101
102 DWORD FileMtime;
103 HANDLE LogThreadEvent;
104 } TFileVar_;
105 typedef TFileVar_ *PFileVar_;
106
107 #define PFileVar PFileVar_
108 #define TFileVar TFileVar_
109
110 static PFileVar LogVar = NULL;
111
112 BOOL FileLog = FALSE;
113 BOOL BinLog = FALSE;
114
115 /*
116 Line Head flag for timestamping
117 2007.05.24 Gentaro
118 */
119 enum enumLineEnd {
120 Line_Other = 0,
121 Line_LineHead = 1,
122 Line_FileHead = 2,
123 };
124
125 static enum enumLineEnd eLineEnd = Line_LineHead;
126
127
128 // �x�����������p�X���b�h�����b�Z�[�W
129 #define WM_DPC_LOGTHREAD_SEND (WM_APP + 1)
130
131 static void CloseFileSync(PFileVar ptr);
132 static void FileTransEnd_(WORD OpId);
133
134
135 static PFileTransDlg FLogDlg = NULL;
136
137 static BOOL OpenFTDlg_(PFileVar fv)
138 {
139 PFileTransDlg FTDlg;
140
141 FTDlg = new CFileTransDlg();
142
143 fv->StartTime = 0;
144 fv->ProgStat = 0;
145 cv.FilePause &= ~fv->OpId;
146
147 if (fv->OpId != OpLog) {
148 fv->HideDialog = ts.FTHideDialog;
149 }
150
151 if (FTDlg!=NULL)
152 {
153 CFileTransDlgInfo info;
154 info.UILanguageFile = ts.UILanguageFile;
155 info.OpId = fv->OpId;
156 info.DlgCaption = fv->DlgCaption;
157 info.FileName = &fv->FullName[fv->DirLen];
158 info.FullName = fv->FullName;
159 info.HideDialog = fv->HideDialog;
160 info.HMainWin = fv->HMainWin;
161 FTDlg->Create(hInst, &info);
162 FTDlg->RefreshNum(fv->StartTime, fv->FileSize, fv->ByteCount);
163 }
164
165 // if (fv->OpId==OpLog)
166 FLogDlg = FTDlg; /* Log */
167 #if 0
168 else
169 SendDlg = FTDlg; /* File send */
170 #endif
171
172 fv->StartTime = GetTickCount();
173
174 return (FTDlg!=NULL);
175 }
176
177 static void ShowFTDlg(WORD OpId)
178 {
179 // if (OpId == OpLog)
180 {
181 if (FLogDlg != NULL) {
182 FLogDlg->ShowWindow(SW_SHOWNORMAL);
183 SetForegroundWindow(FLogDlg->GetSafeHwnd());
184 }
185 }
186 #if 0
187 else {
188 if (SendDlg != NULL) {
189 SendDlg->ShowWindow(SW_SHOWNORMAL);
190 SetForegroundWindow(SendDlg->GetSafeHwnd());
191 }
192 }
193 #endif
194 }
195
196 static BOOL NewFileVar_(PFileVar *fv)
197 {
198 if ((*fv)==NULL)
199 {
200 *fv = (PFileVar)malloc(sizeof(TFileVar));
201 if ((*fv)!=NULL)
202 {
203 char FileDirExpanded[MAX_PATH];
204 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
205 memset(*fv, 0, sizeof(TFileVar));
206 strncpy_s((*fv)->FullName, sizeof((*fv)->FullName), FileDirExpanded, _TRUNCATE);
207 AppendSlash((*fv)->FullName,sizeof((*fv)->FullName));
208 (*fv)->DirLen = strlen((*fv)->FullName);
209 (*fv)->FileOpen = FALSE;
210 (*fv)->OverWrite = ((ts.FTFlag & FT_RENAME) == 0);
211 (*fv)->HMainWin = HVTWin;
212 (*fv)->Success = FALSE;
213 (*fv)->NoMsg = FALSE;
214 (*fv)->HideDialog = FALSE;
215 }
216 }
217
218 return ((*fv)!=NULL);
219 }
220
221 static void FreeFileVar_(PFileVar *fv)
222 {
223 if ((*fv)!=NULL)
224 {
225 CloseFileSync(*fv);
226 //if ((*fv)->FileOpen) _lclose((*fv)->FileHandle);
227 if ((*fv)->FnStrMemHandle != 0)
228 {
229 GlobalUnlock((*fv)->FnStrMemHandle);
230 GlobalFree((*fv)->FnStrMemHandle);
231 }
232 free(*fv);
233 *fv = NULL;
234 }
235 }
236
237 /**
238 * �t�@�C�������������u������
239 * &h �z�X�g�����u�� (2007.5.14)
240 * &p TCP�|�[�g�������u�� (2009.6.12)
241 * &u ���O�I���������[�U��
242 */
243 static void ConvertLogname(char *c, int destlen)
244 {
245 char buf[MAXPATHLEN], buf2[MAXPATHLEN], *p = c;
246 char tmphost[1024];
247 char tmpuser[256+1];
248 DWORD len_user = sizeof(tmpuser);
249
250 memset(buf, 0, sizeof(buf));
251
252 while(*p != '\0') {
253 if (*p == '&' && *(p+1) != '\0') {
254 switch (*(p+1)) {
255 case 'h':
256 if (cv.Open) {
257 if (cv.PortType == IdTCPIP) {
258 // �z�X�g����IPv6�A�h���X�����A�t�@�C�������g�p�����������������������A
259 // �]�v�����������������B
260 // (2013.3.9 yutaka)
261 strncpy_s(tmphost, sizeof(tmphost), ts.HostName, _TRUNCATE);
262 //strncpy_s(tmphost, sizeof(tmphost), "2001:0db8:bd05:01d2:288a:1fc0:0001:10ee", _TRUNCATE);
263 replaceInvalidFileNameChar(tmphost, '_');
264 strncat_s(buf,sizeof(buf), tmphost, _TRUNCATE);
265 }
266 else if (cv.PortType == IdSerial) {
267 strncpy_s(buf2,sizeof(buf2),buf,_TRUNCATE);
268 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%sCOM%d", buf2, ts.ComPort);
269 }
270 }
271 break;
272 case 'p':
273 if (cv.Open) {
274 if (cv.PortType == IdTCPIP) {
275 char port[6];
276 _snprintf_s(port, sizeof(port), _TRUNCATE, "%d", ts.TCPPort);
277 strncat_s(buf,sizeof(buf),port,_TRUNCATE);
278 }
279 }
280 break;
281 case 'u':
282 if (GetUserName(tmpuser, &len_user) != 0) {
283 strncat_s(buf,sizeof(buf),tmpuser,_TRUNCATE);
284 }
285 break;
286 default:
287 strncpy_s(buf2,sizeof(buf2),p,2);
288 strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
289 }
290 p++;
291 }
292 else {
293 strncpy_s(buf2,sizeof(buf2),p,1);
294 strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
295 }
296 p++;
297 }
298 strncpy_s(c, destlen, buf, _TRUNCATE);
299 }
300
301 static void FixLogOption(void)
302 {
303 if (ts.LogBinary) {
304 ts.LogTypePlainText = false;
305 ts.LogTimestamp = false;
306 }
307 }
308
309
310 // �X���b�h���I�����t�@�C�����N���[�Y
311 static void CloseFileSync(PFileVar ptr)
312 {
313 BOOL ret;
314
315 if (!ptr->FileOpen)
316 return;
317
318 if (ptr->LogThread != INVALID_HANDLE_VALUE) {
319 // �X���b�h���I������
320 ret = PostThreadMessage(ptr->LogThreadId, WM_QUIT, 0, 0);
321 if (ret != 0) {
322 // �X���b�h�L���[���G���L���[���������������������������s���B
323 WaitForSingleObject(ptr->LogThread, INFINITE);
324 }
325 else {
326 //DWORD code = GetLastError();
327 }
328 CloseHandle(ptr->LogThread);
329 ptr->LogThread = INVALID_HANDLE_VALUE;
330 }
331 CloseHandle(ptr->FileHandle);
332 }
333
334 // �x�����������p�X���b�h
335 static unsigned _stdcall DeferredLogWriteThread(void *arg)
336 {
337 MSG msg;
338 PFileVar fv = (PFileVar)arg;
339 PCHAR buf;
340 DWORD buflen;
341 DWORD wrote;
342
343 PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
344
345 // �X���b�h�L���[���������I�������������X���b�h�����������m�����B
346 if (fv->LogThreadEvent != NULL) {
347 SetEvent(fv->LogThreadEvent);
348 }
349
350 while (GetMessage(&msg, NULL, 0, 0) > 0) {
351 switch (msg.message) {
352 case WM_DPC_LOGTHREAD_SEND:
353 buf = (PCHAR)msg.wParam;
354 buflen = (DWORD)msg.lParam;
355 WriteFile(LogVar->FileHandle, buf, buflen, &wrote, NULL);
356 free(buf); // ����������������
357 break;
358
359 case WM_QUIT:
360 goto end;
361 break;
362 }
363 }
364
365 end:
366 _endthreadex(0);
367 return (0);
368 }
369
370 /**
371 * �_�C�A���O�����e�� ts ����������
372 *
373 * TODO
374 * �_�C�A���O�����������l�������I��������
375 * ����������������������������������������������?
376 */
377 static void SetLogFlags(HWND Dialog)
378 {
379 WORD BinFlag, val;
380
381 GetRB(Dialog, &BinFlag, IDC_FOPTBIN, IDC_FOPTBIN);
382 ts.LogBinary = BinFlag;
383
384 GetRB(Dialog, &val, IDC_APPEND, IDC_APPEND);
385 ts.Append = val;
386
387 if (!BinFlag) {
388 GetRB(Dialog, &val, IDC_PLAINTEXT, IDC_PLAINTEXT);
389 ts.LogTypePlainText = val;
390
391 GetRB(Dialog, &val, IDC_TIMESTAMP, IDC_TIMESTAMP);
392 ts.LogTimestamp = val;
393 }
394
395 GetRB(Dialog, &val, IDC_HIDEDIALOG, IDC_HIDEDIALOG);
396 ts.LogHideDialog = val;
397
398 GetRB(Dialog, &val, IDC_ALLBUFF_INFIRST, IDC_ALLBUFF_INFIRST);
399 ts.LogAllBuffIncludedInFirst = val;
400
401 ts.LogTimestampType = (GetCurSel(Dialog, IDC_TIMESTAMPTYPE) - 1);
402 }
403
404 /**
405 * ���O�t�@�C���`�F�b�N
406 *
407 * @param[in] filename
408 * @param[out] exist TURE/FALSE
409 * @param[out] bom 0 no BOM (or file not exist)
410 * 1 UTF-8
411 * 2 UTF-16LE
412 * 3 UTF-16BE
413 */
414 static void CheckLogFile(const wchar_t *filename, BOOL *exist, int *bom)
415 {
416 *exist = FALSE;
417 *bom = 0;
418
419 // �t�@�C������������?
420 DWORD logdir = _GetFileAttributesW(filename);
421 if ((logdir != INVALID_FILE_ATTRIBUTES) && ((logdir & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
422 // �t�@�C����������
423 *exist = TRUE;
424
425 // BOM�L��/�����`�F�b�N
426 FILE *fp = __wfopen(filename, L"rb");
427 if (fp != NULL) {
428 unsigned char tmp[4];
429 size_t l = fread(tmp, 1, sizeof(tmp), fp);
430 fclose(fp);
431 if (l < 2) {
432 *bom = 0;
433 } else if (l >= 2 && tmp[0] == 0xff && tmp[1] == 0xfe) {
434 // UTF-16LE
435 *bom = 2;
436 } else if (l >= 2 && tmp[0] == 0xfe && tmp[1] == 0xff) {
437 // UTF-16BE
438 *bom = 3;
439 } else if (l >= 3 && tmp[0] == 0xef && tmp[1] == 0xbb && tmp[2] == 0xbf) {
440 // UTF-8
441 *bom = 1;
442 } else {
443 *bom = 0;
444 }
445 }
446 }
447 }
448
449 typedef struct {
450 FLogDlgInfo_t *info;
451 // work
452 BOOL file_exist;
453 int current_bom;
454 TTTSet *pts;
455 } LogDlgWork_t;
456
457 static void ArrangeControls(HWND Dialog, LogDlgWork_t *work)
458 {
459 if (work->file_exist) {
460 EnableWindow(GetDlgItem(Dialog, IDC_APPEND), TRUE);
461 if (work->pts->Append > 0) {
462 CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_APPEND);
463 }
464 }
465 else {
466 // �t�@�C�������� -> �V�K
467 EnableWindow(GetDlgItem(Dialog, IDC_APPEND), FALSE);
468 CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_NEW_OVERWRITE);
469 }
470
471 if (work->file_exist && IsDlgButtonChecked(Dialog, IDC_APPEND) == BST_CHECKED) {
472 // �t�@�C������������ && append
473 int bom = work->current_bom;
474 if (bom != 0) {
475 // BOM�L��
476 CheckDlgButton(Dialog, IDC_BOM, BST_CHECKED);
477 int cur =
478 bom == 1 ? 0 :
479 bom == 2 ? 1 :
480 bom == 3 ? 2 : 0;
481 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, cur, 0);
482 }
483 else {
484 // BOM����
485 CheckDlgButton(Dialog, IDC_BOM, BST_UNCHECKED);
486 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, 0, 0);
487 }
488 if (IsDlgButtonChecked(Dialog, IDC_FOPTTEXT) == BST_CHECKED) {
489 EnableWindow(GetDlgItem(Dialog, IDC_BOM), FALSE);
490 if (bom != 0) {
491 // BOM�L��
492 EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), FALSE);
493 }
494 else {
495 // BOM����
496 EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), TRUE);
497 }
498 }
499 }
500 else {
501 // �t�@�C�������� ���� append��������(������)
502 CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_NEW_OVERWRITE);
503 CheckDlgButton(Dialog, IDC_BOM, BST_CHECKED);
504 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, 0, 0);
505 if (IsDlgButtonChecked(Dialog, IDC_FOPTTEXT) == BST_CHECKED) {
506 EnableWindow(GetDlgItem(Dialog, IDC_BOM), TRUE);
507 }
508 }
509 }
510
511 static void CheckLogFile(HWND Dialog, const wchar_t *filename, LogDlgWork_t *work)
512 {
513 BOOL exist;
514 int bom;
515 CheckLogFile(filename, &exist, &bom);
516 work->file_exist = exist;
517 work->current_bom = bom;
518 ArrangeControls(Dialog, work);
519 }
520
521 static INT_PTR CALLBACK LogFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam)
522 {
523 static const DlgTextInfo TextInfos[] = {
524 { 0, "DLG_TABSHEET_TITLE_LOG" },
525 { IDC_FOPTBIN, "DLG_FOPT_BINARY" },
526 { IDC_APPEND, "DLG_FOPT_APPEND" },
527 { IDC_PLAINTEXT, "DLG_FOPT_PLAIN" },
528 { IDC_HIDEDIALOG, "DLG_FOPT_HIDEDIALOG" },
529 { IDC_ALLBUFF_INFIRST, "DLG_FOPT_ALLBUFFINFIRST" },
530 { IDC_TIMESTAMP, "DLG_FOPT_TIMESTAMP" },
531 };
532 static const I18nTextInfo timestamp_list[] = {
533 { "DLG_FOPT_TIMESTAMP_LOCAL", L"Local Time" },
534 { "DLG_FOPT_TIMESTAMP_UTC", L"UTC" },
535 { "DLG_FOPT_TIMESTAMP_ELAPSED_LOGGING", L"Elapsed Time (Logging)" },
536 { "DLG_FOPT_TIMESTAMP_ELAPSED_CONNECTION", L"Elapsed Time (Connection)" },
537 };
538 LogDlgWork_t *work = (LogDlgWork_t *)GetWindowLongPtr(Dialog, DWLP_USER);
539
540 if (Message == RegisterWindowMessage(HELPMSGSTRING)) {
541 // �R�����_�C�A���O�������w���v���b�Z�[�W���t��������
542 Message = WM_COMMAND;
543 wParam = IDHELP;
544 }
545 switch (Message) {
546 case WM_INITDIALOG: {
547 work = (LogDlgWork_t *)lParam;
548 TTTSet *pts = work->pts;
549 const char *UILanguageFile = pts->UILanguageFile;
550 SetWindowLongPtr(Dialog, DWLP_USER, (LONG_PTR)work);
551 ::DragAcceptFiles(Dialog, TRUE);
552
553 SetDlgTexts(Dialog, TextInfos, _countof(TextInfos), UILanguageFile);
554 SetI18nList("Tera Term", Dialog, IDC_TIMESTAMPTYPE, timestamp_list, _countof(timestamp_list),
555 UILanguageFile, 0);
556
557 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_ADDSTRING, 0, (LPARAM)"UTF-8");
558 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_ADDSTRING, 0, (LPARAM)"UTF-16LE");
559 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_ADDSTRING, 0, (LPARAM)"UTF-16BE");
560 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, 0, 0);
561
562 _SetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, work->info->filename);
563 work->info->filename = NULL;
564
565 // Binary/Text �`�F�b�N�{�b�N�X
566 if (pts->LogBinary) {
567 CheckRadioButton(Dialog, IDC_FOPTBIN, IDC_FOPTTEXT, IDC_FOPTBIN);
568 }
569 else {
570 CheckRadioButton(Dialog, IDC_FOPTBIN, IDC_FOPTTEXT, IDC_FOPTTEXT);
571 }
572
573 // Plain Text �`�F�b�N�{�b�N�X
574 if (pts->LogBinary) {
575 // Binary�t���O���L�����������`�F�b�N��������
576 DisableDlgItem(Dialog, IDC_PLAINTEXT, IDC_PLAINTEXT);
577 }
578 else if (pts->LogTypePlainText) {
579 SetRB(Dialog, 1, IDC_PLAINTEXT, IDC_PLAINTEXT);
580 }
581
582 // Hide dialog�`�F�b�N�{�b�N�X (2008.1.30 maya)
583 if (pts->LogHideDialog) {
584 SetRB(Dialog, 1, IDC_HIDEDIALOG, IDC_HIDEDIALOG);
585 }
586
587 // Include screen buffer�`�F�b�N�{�b�N�X (2013.9.29 yutaka)
588 if (pts->LogAllBuffIncludedInFirst) {
589 SetRB(Dialog, 1, IDC_ALLBUFF_INFIRST, IDC_ALLBUFF_INFIRST);
590 }
591
592 // timestamp�`�F�b�N�{�b�N�X (2006.7.23 maya)
593 if (pts->LogBinary) {
594 // Binary�t���O���L�����������`�F�b�N��������
595 DisableDlgItem(Dialog, IDC_TIMESTAMP, IDC_TIMESTAMP);
596 }
597 else if (pts->LogTimestamp) {
598 SetRB(Dialog, 1, IDC_TIMESTAMP, IDC_TIMESTAMP);
599 }
600
601 // timestamp ����
602 int tstype = pts->LogTimestampType == TIMESTAMP_LOCAL ? 0 :
603 pts->LogTimestampType == TIMESTAMP_UTC ? 1 :
604 pts->LogTimestampType == TIMESTAMP_ELAPSED_LOGSTART ? 2 :
605 pts->LogTimestampType == TIMESTAMP_ELAPSED_CONNECTED ? 3 : 0;
606 SendDlgItemMessage(Dialog, IDC_TIMESTAMPTYPE, CB_SETCURSEL, tstype, 0);
607 if (pts->LogBinary || !pts->LogTimestamp) {
608 DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
609 }
610
611 CenterWindow(Dialog, GetParent(Dialog));
612
613 return TRUE;
614 }
615
616 case WM_COMMAND:
617 switch (LOWORD(wParam)) {
618 case IDOK: {
619 wchar_t filename[MAX_PATH];
620 _GetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, filename, _countof(filename));
621 work->info->filename = _wcsdup(filename);
622 work->info->append = IsDlgButtonChecked(Dialog, IDC_APPEND) == BST_CHECKED;
623 work->info->bom = IsDlgButtonChecked(Dialog, IDC_BOM) == BST_CHECKED;
624 work->info->code = (int)SendDlgItemMessageA(Dialog, IDC_TEXTCODING_DROPDOWN, CB_GETCURSEL, 0, 0);
625 SetLogFlags(Dialog);
626 EndDialog(Dialog, IDOK);
627 break;
628 }
629 case IDCANCEL:
630 EndDialog(Dialog, IDCANCEL);
631 break;
632 case IDHELP:
633 OpenHelp(HH_HELP_CONTEXT, HlpFileLog, work->pts->UILanguageFile);
634 break;
635 case IDC_FOPT_FILENAME_BUTTON: {
636 /* save current dir */
637 const char *UILanguageFile = work->pts->UILanguageFile;
638 wchar_t curdir[MAXPATHLEN];
639 _GetCurrentDirectoryW(_countof(curdir), curdir);
640
641 wchar_t fname[MAX_PATH];
642 GetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, fname, _countof(fname));
643
644 wchar_t FNFilter[128*3];
645 get_lang_msgW("FILEDLG_ALL_FILTER", FNFilter, sizeof(FNFilter), L"All(*.*)\\0*.*\\0\\0", UILanguageFile);
646
647 wchar_t caption[MAX_PATH];
648 wchar_t uimsg[MAX_UIMSG];
649 #define TitLogW L"Log"
650 get_lang_msgW("FILEDLG_TRANS_TITLE_LOG", uimsg, _countof(uimsg), TitLogW, UILanguageFile);
651 wcsncpy_s(caption, _countof(caption), L"Tera Term: ", _TRUNCATE);
652 wcsncat_s(caption, _countof(caption), uimsg, _TRUNCATE);
653
654 OPENFILENAMEW ofn = {};
655 ofn.lStructSize = get_OPENFILENAME_SIZEW();
656 //ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
657 ofn.Flags |= OFN_EXPLORER | OFN_ENABLESIZING;
658 ofn.Flags |= OFN_SHOWHELP;
659 ofn.Flags |= OFN_NOCHANGEDIR; // ��������������������������������
660 ofn.hwndOwner = Dialog;
661 ofn.lpstrFilter = FNFilter;
662 ofn.nFilterIndex = 1;
663 ofn.lpstrFile = fname;
664 ofn.nMaxFile = _countof(fname);
665 ofn.lpstrTitle = caption;
666 BOOL Ok = GetSaveFileNameW(&ofn);
667 if (Ok) {
668 SetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, fname);
669 }
670
671 /* restore dir */
672 _SetCurrentDirectoryW(curdir);
673
674 break;
675 }
676 case IDC_FOPTBIN:
677 EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), FALSE);
678 EnableWindow(GetDlgItem(Dialog, IDC_BOM), FALSE);
679 DisableDlgItem(Dialog, IDC_PLAINTEXT, IDC_TIMESTAMP);
680 DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
681 break;
682 case IDC_FOPTTEXT:
683 ArrangeControls(Dialog, work);
684 EnableDlgItem(Dialog, IDC_PLAINTEXT, IDC_TIMESTAMP);
685 // FALLTHROUGH -- BinFlag �� off ������ Timestamp �������L��/��������������
686 case IDC_TIMESTAMP:
687 if (IsDlgButtonChecked(Dialog, IDC_TIMESTAMP) == BST_CHECKED) {
688 EnableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
689 }
690 else {
691 DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
692 }
693 break;
694 case IDC_FOPT_FILENAME_EDIT:
695 if (HIWORD(wParam) == EN_CHANGE){
696 wchar_t filename[MAX_PATH];
697 GetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, filename, _countof(filename));
698 CheckLogFile(Dialog, filename, work);
699 }
700 break;
701 case IDC_NEW_OVERWRITE:
702 if (IsDlgButtonChecked(Dialog, IDC_FOPTTEXT) == BST_CHECKED) {
703 EnableWindow(GetDlgItem(Dialog, IDC_BOM), TRUE);
704 EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), TRUE);
705 CheckDlgButton(Dialog, IDC_BOM, BST_CHECKED);
706 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, 0, 0);
707 }
708 break;
709 case IDC_APPEND:
710 ArrangeControls(Dialog, work);
711 break;
712 }
713 break;
714 case WM_DROPFILES: {
715 // �����h���b�v��������������1������������
716 HDROP hDrop = (HDROP)wParam;
717 const UINT len = _DragQueryFileW(hDrop, 0, NULL, 0);
718 if (len == 0) {
719 DragFinish(hDrop);
720 return TRUE;
721 }
722 wchar_t *filename = (wchar_t *)malloc(sizeof(wchar_t) * (len + 1));
723 _DragQueryFileW(hDrop, 0, filename, len + 1);
724 filename[len] = '\0';
725 CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_APPEND);
726 _SetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, filename);
727 SendDlgItemMessage(Dialog, IDC_FOPT_FILENAME_EDIT, EM_SETSEL, len, len);
728 free(filename);
729 DragFinish(hDrop);
730 return TRUE;
731 }
732 }
733 return FALSE;
734 }
735
736 static BOOL LogStart(void)
737 {
738 unsigned tid;
739
740 if ((FileLog) || (BinLog)) return FALSE;
741
742 assert(LogVar != NULL);
743
744 if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0) {
745 // �t�@�C����������������������
746 return FALSE;
747 }
748
749 if (! LoadTTFILE()) return FALSE;
750
751 LogVar->OpId = OpLog;
752 //(*SetFileVar)(LogVar);
753 {
754 int i;
755 char c;
756 PFileVar fv = LogVar;
757 GetFileNamePos(fv->FullName,&(fv->DirLen),&i);
758 c = fv->FullName[fv->DirLen];
759 if (c=='\\'||c=='/') fv->DirLen++;
760 strncpy_s(fv->DlgCaption, sizeof(fv->DlgCaption),"Tera Term: ", _TRUNCATE);
761 char uimsg[MAX_UIMSG];
762 get_lang_msg("FILEDLG_TRANS_TITLE_LOG", uimsg, sizeof(uimsg), TitLog, ts.UILanguageFile);
763 strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE);
764 }
765 FixLogOption();
766
767 if (ts.LogBinary > 0)
768 {
769 BinLog = TRUE;
770 FileLog = FALSE;
771 if (! CreateBinBuf())
772 {
773 FileTransEnd_(OpLog);
774 return FALSE;
775 }
776 }
777 else {
778 BinLog = FALSE;
779 FileLog = TRUE;
780 if (! CreateLogBuf())
781 {
782 FileTransEnd_(OpLog);
783 return FALSE;
784 }
785 }
786 cv.LStart = cv.LogPtr;
787 cv.LCount = 0;
788 if (ts.LogHideDialog)
789 LogVar->HideDialog = 1;
790
791 /* 2007.05.24 Gentaro */
792 eLineEnd = Line_LineHead;
793
794 if (ts.Append > 0)
795 {
796 int dwShareMode = FILE_SHARE_READ;
797 if (!ts.LogLockExclusive) {
798 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
799 }
800 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
801 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
802 if (LogVar->FileHandle != INVALID_HANDLE_VALUE){
803 SetFilePointer(LogVar->FileHandle, 0, NULL, FILE_END);
804 /* 2007.05.24 Gentaro
805 If log file already exists,
806 a newline is inserted before the first timestamp.
807 */
808 eLineEnd = Line_FileHead;
809 }
810 }
811 else {
812 int dwShareMode = FILE_SHARE_READ;
813 if (!ts.LogLockExclusive) {
814 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
815 }
816 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
817 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
818 }
819 LogVar->FileOpen = (LogVar->FileHandle != INVALID_HANDLE_VALUE);
820 if (! LogVar->FileOpen)
821 {
822 char msg[128];
823
824 // �t�@�C���I�[�v���G���[�������b�Z�[�W�\�������������B(2008.7.9 yutaka)
825 if (LogVar->NoMsg == FALSE) {
826 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Can not create a `%s' file. (%d)", LogVar->FullName, GetLastError());
827 MessageBox(NULL, msg, "Tera Term: File open error", MB_OK | MB_ICONERROR);
828 }
829
830 FileTransEnd_(OpLog);
831 return FALSE;
832 }
833 LogVar->ByteCount = 0;
834
835 // Log rotate configuration
836 LogVar->RotateMode = ts.LogRotate;
837 LogVar->RotateSize = ts.LogRotateSize;
838 LogVar->RotateStep = ts.LogRotateStep;
839
840 // Log rotate���L���������A�����t�@�C���T�C�Y�����������B
841 // �������t�@�C�������������T�C�Y�����[�e�[�g�������������C���B
842 // (2016.4.9 yutaka)
843 if (LogVar->RotateMode != ROTATE_NONE) {
844 DWORD size = GetFileSize(LogVar->FileHandle, NULL);
845 if (size != -1)
846 LogVar->ByteCount = size;
847 }
848
849 if (! OpenFTDlg_(LogVar)) {
850 FileTransEnd_(OpLog);
851 return FALSE;
852 }
853
854 // �x�����������p�X���b�h���N�����B
855 // (2013.4.19 yutaka)
856 // DeferredLogWriteThread �X���b�h���N�������A�X���b�h�L���[�����������������O���A
857 // ���O�t�@�C�����N���[�Y(CloseFileSync)���s���������A�G���L���[�����s���A�f�b�h���b�N
858 // �����������������C�������B
859 // �X���b�h�����������s�������A���O�����C�x���g�I�u�W�F�N�g���g�����A�X���b�h�L���[��
860 // ���������������������������������B���O�t���C�x���g�I�u�W�F�N�g���g���������A
861 // �V�X�e��(Windows OS)�������j�[�N�����O�������K�v�������B
862 // (2016.9.23 yutaka)
863 LogVar->LogThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
864 LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
865 LogVar->LogThreadId = tid;
866 if (LogVar->LogThreadEvent != NULL) {
867 WaitForSingleObject(LogVar->LogThreadEvent, INFINITE);
868 CloseHandle(LogVar->LogThreadEvent);
869 }
870
871 // �����o�b�t�@�������f�[�^�������������o���������A
872 // ���O�������J�n�����B
873 // (2013.9.29 yutaka)
874 if (ts.LogAllBuffIncludedInFirst) {
875 DWORD ofs, size, written_size;
876 char buf[512];
877 const char *crlf = "\r\n";
878 DWORD crlf_len = 2;
879 for (ofs = 0 ; ; ofs++ ) {
880 // 1�����s�����������B���������������A�G�X�P�[�v�V�[�P���X�������������B
881 size = BuffGetAnyLineData(ofs, buf, sizeof(buf));
882 if (size == -1)
883 break;
884
885 #if 0
886 if (ts.DeferredLogWriteMode) { // �x����������
887 char *pbuf = (char *)malloc(size + 2);
888 memcpy(pbuf, buf, size);
889 pbuf[size] = '\r';
890 pbuf[size+1] = '\n';
891 Sleep(1); // �X���b�h�L���[�����������������A�R���e�L�X�g�X�C�b�`�������B
892 PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)pbuf, size + 2);
893 } else { // �������B�l�b�g���[�N�o�R�����x���B
894 #endif
895 WriteFile(LogVar->FileHandle, buf, size, &written_size, NULL);
896 WriteFile(LogVar->FileHandle, crlf, crlf_len, &written_size, NULL);
897 #if 0
898 }
899 #endif
900 }
901 }
902
903 return TRUE;
904 }
905
906 void LogPut1(BYTE b)
907 {
908 cv.LogBuf[cv.LogPtr] = b;
909 cv.LogPtr++;
910 if (cv.LogPtr>=InBuffSize)
911 cv.LogPtr = cv.LogPtr-InBuffSize;
912
913 if (FileLog)
914 {
915 if (cv.LCount>=InBuffSize)
916 {
917 cv.LCount = InBuffSize;
918 cv.LStart = cv.LogPtr;
919 }
920 else
921 cv.LCount++;
922 }
923 else
924 cv.LCount = 0;
925 }
926
927 static BOOL Get1(PCHAR Buf, int *Start, int *Count, PBYTE b)
928 {
929 if (*Count<=0) return FALSE;
930 *b = Buf[*Start];
931 (*Start)++;
932 if (*Start>=InBuffSize)
933 *Start = *Start-InBuffSize;
934 (*Count)--;
935 return TRUE;
936 }
937
938
939
940 static CRITICAL_SECTION g_filelog_lock; /* ���b�N�p���� */
941
942 void logfile_lock_initialize(void)
943 {
944 InitializeCriticalSection(&g_filelog_lock);
945 }
946
947 static inline void logfile_lock(void)
948 {
949 EnterCriticalSection(&g_filelog_lock);
950 }
951
952 static inline void logfile_unlock(void)
953 {
954 LeaveCriticalSection(&g_filelog_lock);
955 }
956
957 // �R�����g�����O����������
958 static void CommentLogToFile(char *buf, int size)
959 {
960 DWORD wrote;
961
962 if (LogVar == NULL || !LogVar->FileOpen) {
963 char uimsg[MAX_UIMSG];
964 get_lang_msg("MSG_ERROR", uimsg, sizeof(uimsg), "ERROR", ts.UILanguageFile);
965 get_lang_msg("MSG_COMMENT_LOG_OPEN_ERROR", ts.UIMsg, sizeof(ts.UIMsg),
966 "It is not opened by the log file yet.", ts.UILanguageFile);
967 ::MessageBox(NULL, ts.UIMsg, uimsg, MB_OK|MB_ICONEXCLAMATION);
968 return;
969 }
970
971 logfile_lock();
972 WriteFile(LogVar->FileHandle, buf, size, &wrote, NULL);
973 WriteFile(LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // ���s
974 /* Set Line End Flag
975 2007.05.24 Gentaro
976 */
977 eLineEnd = Line_LineHead;
978 logfile_unlock();
979 }
980
981 // ���O�����[�e�[�g�����B
982 // (2013.3.21 yutaka)
983 static void LogRotate(void)
984 {
985 int loopmax = 10000; // XXX
986 char filename[1024];
987 char newfile[1024], oldfile[1024];
988 int i, k;
989 int dwShareMode = FILE_SHARE_READ;
990 unsigned tid;
991
992 if (! LogVar->FileOpen) return;
993
994 if (LogVar->RotateMode == ROTATE_NONE)
995 return;
996
997 if (LogVar->RotateMode == ROTATE_SIZE) {
998 if (LogVar->ByteCount <= LogVar->RotateSize)
999 return;
1000 //OutputDebugPrintf("%s: mode %d size %ld\n", __FUNCTION__, LogVar->RotateMode, LogVar->ByteCount);
1001 } else {
1002 return;
1003 }
1004
1005 logfile_lock();
1006 // ���O�T�C�Y���������������B
1007 LogVar->ByteCount = 0;
1008
1009 // �������������t�@�C�����N���[�Y�����A�������t�@�C�����I�[�v�������B
1010 CloseFileSync(LogVar);
1011 //_lclose(LogVar->FileHandle);
1012
1013 // �������[�e�[�V�������X�e�b�v�����w����������
1014 if (LogVar->RotateStep > 0)
1015 loopmax = LogVar->RotateStep;
1016
1017 for (i = 1 ; i <= loopmax ; i++) {
1018 _snprintf_s(filename, sizeof(filename), _TRUNCATE, "%s.%d", LogVar->FullName, i);
1019 if (_access_s(filename, 0) != 0)
1020 break;
1021 }
1022 if (i > loopmax) {
1023 // �������������������������A�������t�@�C�������p�������B
1024 i = loopmax;
1025 }
1026
1027 // ���t�@�C�������l�[���B
1028 for (k = i-1 ; k >= 0 ; k--) {
1029 if (k == 0)
1030 strncpy_s(oldfile, sizeof(oldfile), LogVar->FullName, _TRUNCATE);
1031 else
1032 _snprintf_s(oldfile, sizeof(oldfile), _TRUNCATE, "%s.%d", LogVar->FullName, k);
1033 _snprintf_s(newfile, sizeof(newfile), _TRUNCATE, "%s.%d", LogVar->FullName, k+1);
1034 remove(newfile);
1035 if (rename(oldfile, newfile) != 0) {
1036 OutputDebugPrintf("%s: rename %d\n", __FUNCTION__, errno);
1037 }
1038 }
1039
1040 // ���I�[�v��
1041 if (!ts.LogLockExclusive) {
1042 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1043 }
1044 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
1045 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1046
1047 // �x�����������p�X���b�h���N�����B
1048 // (2013.4.19 yutaka)
1049 // DeferredLogWriteThread �X���b�h���N�������A�X���b�h�L���[�����������������O���A
1050 // ���O�t�@�C�����N���[�Y(CloseFileSync)���s���������A�G���L���[�����s���A�f�b�h���b�N
1051 // �����������������C�������B
1052 // �X���b�h�����������s�������A���O�����C�x���g�I�u�W�F�N�g���g�����A�X���b�h�L���[��
1053 // ���������������������������������B���O�t���C�x���g�I�u�W�F�N�g���g���������A
1054 // �V�X�e��(Windows OS)�������j�[�N�����O�������K�v�������B
1055 // (2016.9.26 yutaka)
1056 LogVar->LogThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1057 LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
1058 LogVar->LogThreadId = tid;
1059 if (LogVar->LogThreadEvent != NULL) {
1060 WaitForSingleObject(LogVar->LogThreadEvent, INFINITE);
1061 CloseHandle(LogVar->LogThreadEvent);
1062 }
1063
1064 logfile_unlock();
1065
1066 }
1067
1068 void LogToFile(void)
1069 {
1070 PCHAR Buf;
1071 int Start, Count;
1072 BYTE b;
1073 PCHAR WriteBuf;
1074 DWORD WriteBufMax, WriteBufLen;
1075 CHAR tmp[128];
1076 DWORD wrote;
1077
1078 if (! LogVar->FileOpen) return;
1079 if (FileLog)
1080 {
1081 Buf = cv.LogBuf;
1082 Start = cv.LStart;
1083 Count = cv.LCount;
1084 }
1085 else if (BinLog)
1086 {
1087 Buf = cv.BinBuf;
1088 Start = cv.BStart;
1089 Count = cv.BCount;
1090 }
1091 else
1092 return;
1093
1094 if (Buf==NULL) return;
1095 if (Count==0) return;
1096
1097 // ���b�N������(2004.8.6 yutaka)
1098 logfile_lock();
1099
1100 if (ts.DeferredLogWriteMode) {
1101 WriteBufMax = 8192;
1102 WriteBufLen = 0;
1103 WriteBuf = (PCHAR)malloc(WriteBufMax);
1104 while (Get1(Buf,&Start,&Count,&b)) {
1105 if (!FLogIsPause() && (! cv.ProtoFlag))
1106 {
1107 tmp[0] = 0;
1108 if ( ts.LogTimestamp && eLineEnd ) {
1109 char *strtime = NULL;
1110
1111 switch (ts.LogTimestampType) {
1112 case TIMESTAMP_LOCAL:
1113 strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
1114 break;
1115 case TIMESTAMP_UTC:
1116 strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
1117 break;
1118 case TIMESTAMP_ELAPSED_LOGSTART:
1119 strtime = strelapsed(LogVar->StartTime);
1120 break;
1121 case TIMESTAMP_ELAPSED_CONNECTED:
1122 strtime = strelapsed(cv.ConnectedTime);
1123 break;
1124 }
1125
1126 /* 2007.05.24 Gentaro */
1127 if( eLineEnd == Line_FileHead ){
1128 strncat_s(tmp, sizeof(tmp), "\r\n", _TRUNCATE);
1129 }
1130 strncat_s(tmp, sizeof(tmp), "[", _TRUNCATE);
1131 strncat_s(tmp, sizeof(tmp), strtime, _TRUNCATE);
1132 strncat_s(tmp, sizeof(tmp), "] ", _TRUNCATE);
1133 }
1134
1135 /* 2007.05.24 Gentaro */
1136 if( b == 0x0a ){
1137 eLineEnd = Line_LineHead; /* set endmark*/
1138 }
1139 else {
1140 eLineEnd = Line_Other; /* clear endmark*/
1141 }
1142
1143 if (WriteBufLen >= (WriteBufMax*4/5)) {
1144 WriteBufMax *= 2;
1145 WriteBuf = (PCHAR)realloc(WriteBuf, WriteBufMax);
1146 }
1147 memcpy(&WriteBuf[WriteBufLen], tmp, strlen(tmp));
1148 WriteBufLen += strlen(tmp);
1149 WriteBuf[WriteBufLen++] = b;
1150
1151 (LogVar->ByteCount)++;
1152 }
1153 }
1154
1155 PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)WriteBuf, WriteBufLen);
1156
1157 } else {
1158
1159 while (Get1(Buf,&Start,&Count,&b))
1160 {
1161 if (!FLogIsPause() && (! cv.ProtoFlag))
1162 {
1163 if ( ts.LogTimestamp && eLineEnd ) {
1164 char *strtime = NULL;
1165
1166 switch (ts.LogTimestampType) {
1167 case TIMESTAMP_LOCAL:
1168 strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
1169 break;
1170 case TIMESTAMP_UTC:
1171 strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
1172 break;
1173 case TIMESTAMP_ELAPSED_LOGSTART:
1174 strtime = strelapsed(LogVar->StartTime);
1175 break;
1176 case TIMESTAMP_ELAPSED_CONNECTED:
1177 strtime = strelapsed(cv.ConnectedTime);
1178 break;
1179 }
1180 WriteFile(LogVar->FileHandle, "[", 1, &wrote, NULL);
1181 WriteFile(LogVar->FileHandle, strtime, strlen(strtime), &wrote, NULL);
1182 WriteFile(LogVar->FileHandle, "] ", 2, &wrote, NULL);
1183 }
1184
1185 /* 2007.05.24 Gentaro */
1186 if( b == 0x0a ){
1187 eLineEnd = Line_LineHead; /* set endmark*/
1188 }
1189 else {
1190 eLineEnd = Line_Other; /* clear endmark*/
1191 }
1192
1193 WriteFile(LogVar->FileHandle, (PCHAR)&b, 1, &wrote, NULL);
1194 (LogVar->ByteCount)++;
1195 }
1196 }
1197
1198 }
1199
1200 logfile_unlock();
1201
1202 if (FileLog)
1203 {
1204 cv.LStart = Start;
1205 cv.LCount = Count;
1206 }
1207 else {
1208 cv.BStart = Start;
1209 cv.BCount = Count;
1210 }
1211 if (FLogIsPause() || cv.ProtoFlag) return;
1212 if (FLogDlg!=NULL)
1213 //FLogDlg->RefreshNum(LogVar);
1214 FLogDlg->RefreshNum(LogVar->StartTime, LogVar->FileSize, LogVar->ByteCount);
1215
1216
1217 // ���O�E���[�e�[�g
1218 LogRotate();
1219
1220 }
1221
1222 BOOL CreateLogBuf(void)
1223 {
1224 if (cv.HLogBuf==NULL)
1225 {
1226 cv.HLogBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1227 cv.LogBuf = NULL;
1228 cv.LogPtr = 0;
1229 cv.LStart = 0;
1230 cv.LCount = 0;
1231 }
1232 return (cv.HLogBuf!=NULL);
1233 }
1234
1235 void FreeLogBuf(void)
1236 {
1237 if ((cv.HLogBuf==NULL) || FileLog)
1238 return;
1239 if (cv.LogBuf!=NULL)
1240 GlobalUnlock(cv.HLogBuf);
1241 GlobalFree(cv.HLogBuf);
1242 cv.HLogBuf = NULL;
1243 cv.LogBuf = NULL;
1244 cv.LogPtr = 0;
1245 cv.LStart = 0;
1246 cv.LCount = 0;
1247 }
1248
1249 BOOL CreateBinBuf(void)
1250 {
1251 if (cv.HBinBuf==NULL)
1252 {
1253 cv.HBinBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1254 cv.BinBuf = NULL;
1255 cv.BinPtr = 0;
1256 cv.BStart = 0;
1257 cv.BCount = 0;
1258 }
1259 return (cv.HBinBuf!=NULL);
1260 }
1261
1262 void FreeBinBuf(void)
1263 {
1264 if ((cv.HBinBuf==NULL) || BinLog)
1265 return;
1266 if (cv.BinBuf!=NULL)
1267 GlobalUnlock(cv.HBinBuf);
1268 GlobalFree(cv.HBinBuf);
1269 cv.HBinBuf = NULL;
1270 cv.BinBuf = NULL;
1271 cv.BinPtr = 0;
1272 cv.BStart = 0;
1273 cv.BCount = 0;
1274 }
1275
1276 static void FileTransEnd_(WORD OpId)
1277 /* OpId = 0: close Log and FileSend
1278 OpLog: close Log
1279 OpSendFile: close FileSend */
1280 {
1281 if (((OpId==0) || (OpId==OpLog)) && (FileLog || BinLog))
1282 {
1283 FileLog = FALSE;
1284 BinLog = FALSE;
1285 if (FLogDlg!=NULL)
1286 {
1287 FLogDlg->DestroyWindow();
1288 FLogDlg = NULL;
1289 }
1290 FreeFileVar_(&LogVar);
1291 FreeLogBuf();
1292 FreeBinBuf();
1293 FreeTTFILE();
1294 }
1295
1296 #if 0
1297 if (((OpId==0) || (OpId==OpSendFile)) && FSend)
1298 {
1299 FSend = FALSE;
1300 TalkStatus = IdTalkKeyb;
1301 if (SendDlg!=NULL)
1302 {
1303 SendDlg->DestroyWindow();
1304 SendDlg = NULL;
1305 }
1306 FreeFileVar_(&SendVar);
1307 FreeTTFILE();
1308 }
1309 #endif
1310
1311 // EndDdeCmnd(0);
1312 }
1313
1314
1315 /**
1316 * ���O���|�[�Y����
1317 * ���� FLogChangeButton() ������
1318 */
1319 void FLogPause(BOOL Pause)
1320 {
1321 if (FLogDlg!=NULL)
1322 FLogDlg->ChangeButton(Pause);
1323 FileTransPause(OpLog, Pause);
1324 }
1325
1326 /**
1327 * ���O���[�e�[�g������
1328 * ���O���T�C�Y��<size>�o�C�g���������������A���[�e�[�V��������������������
1329 */
1330 void FLogRotateSize(size_t size)
1331 {
1332 if (LogVar == NULL) {
1333 return;
1334 }
1335 LogVar->RotateMode = ROTATE_SIZE;
1336 LogVar->RotateSize = size;
1337 }
1338
1339 /**
1340 * ���O���[�e�[�g������
1341 * ���O�t�@�C������������������
1342 */
1343 void FLogRotateRotate(int step)
1344 {
1345 if (LogVar == NULL) {
1346 return;
1347 }
1348 LogVar->RotateStep = step;
1349 }
1350
1351 /**
1352 * ���O���[�e�[�g������
1353 * ���[�e�[�V���������~
1354 */
1355 void FLogRotateHalt(void)
1356 {
1357 if (LogVar == NULL) {
1358 return;
1359 }
1360 LogVar->RotateMode = ROTATE_NONE;
1361 LogVar->RotateSize = 0;
1362 LogVar->RotateStep = 0;
1363 }
1364
1365 static INT_PTR CALLBACK OnCommentDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp)
1366 {
1367 static const DlgTextInfo TextInfos[] = {
1368 { 0, "DLG_COMMENT_TITLE" },
1369 { IDOK, "BTN_OK" }
1370 };
1371 char buf[256];
1372 UINT ret;
1373
1374 switch (msg) {
1375 case WM_INITDIALOG:
1376 //SetDlgItemText(hDlgWnd, IDC_EDIT_COMMENT, "�T���v��");
1377 // �G�f�B�b�g�R���g���[�����t�H�[�J�X��������
1378 SetFocus(GetDlgItem(hDlgWnd, IDC_EDIT_COMMENT));
1379 SetDlgTexts(hDlgWnd, TextInfos, _countof(TextInfos), ts.UILanguageFile);
1380 return FALSE;
1381
1382 case WM_COMMAND:
1383 switch (LOWORD(wp)) {
1384 case IDOK:
1385 memset(buf, 0, sizeof(buf));
1386 ret = GetDlgItemTextA(hDlgWnd, IDC_EDIT_COMMENT, buf, sizeof(buf) - 1);
1387 if (ret > 0) { // �e�L�X�g��������
1388 //buf[sizeof(buf) - 1] = '\0'; // null-terminate
1389 CommentLogToFile(buf, ret);
1390 }
1391 TTEndDialog(hDlgWnd, IDOK);
1392 break;
1393 default:
1394 return FALSE;
1395 }
1396 break;
1397 case WM_CLOSE:
1398 TTEndDialog(hDlgWnd, 0);
1399 return TRUE;
1400
1401 default:
1402 return FALSE;
1403 }
1404 return TRUE;
1405 }
1406
1407 void FLogAddCommentDlg(HINSTANCE hInst, HWND hWnd)
1408 {
1409 // ���O�t�@�C�����R�����g���������� (2004.8.6 yutaka)
1410 TTDialogBox(hInst, MAKEINTRESOURCE(IDD_COMMENT_DIALOG),
1411 HVTWin, OnCommentDlgProc);
1412 }
1413
1414 void FLogClose(void)
1415 {
1416 if (LogVar != NULL)
1417 FileTransEnd_(OpLog);
1418 }
1419
1420 BOOL FLogOpen(const char *fname)
1421 {
1422 BOOL ret;
1423
1424 if (LogVar != NULL) {
1425 return FALSE;
1426 }
1427
1428 LogVar->DirLen = 0;
1429 LogVar->NoMsg = TRUE;
1430 strncpy_s(LogVar->FullName, sizeof(LogVar->FullName), fname, _TRUNCATE);
1431 ret = LogStart();
1432 return ret;
1433 }
1434
1435 BOOL FLogIsOpend(void)
1436 {
1437 // LogVar->FileOpen
1438 return LogVar != NULL;
1439 }
1440
1441 void FLogWriteStr(const char *str)
1442 {
1443 if (LogVar != NULL)
1444 {
1445 DWORD wrote;
1446 size_t len = strlen(str);
1447 WriteFile(LogVar->FileHandle, str, len, &wrote, NULL);
1448 LogVar->ByteCount =
1449 LogVar->ByteCount + len;
1450 if (FLogDlg!=NULL)
1451 //FLogDlg->RefreshNum(LogVar);
1452 FLogDlg->RefreshNum(LogVar->StartTime, LogVar->FileSize, LogVar->ByteCount);
1453 }
1454 }
1455
1456 void FLogInfo(char *param_ptr, size_t param_len)
1457 {
1458 if (LogVar) {
1459 param_ptr[0] = '0'
1460 + (ts.LogBinary != 0)
1461 + ((ts.Append != 0) << 1)
1462 + ((ts.LogTypePlainText != 0) << 2)
1463 + ((ts.LogTimestamp != 0) << 3)
1464 + ((ts.LogHideDialog != 0) << 4);
1465 strncpy_s(param_ptr + 1, param_len - 1, LogVar->FullName, _TRUNCATE);
1466 }
1467 else {
1468 param_ptr[0] = '0' - 1;
1469 param_ptr[1] = 0;
1470 }
1471 }
1472
1473 /**
1474 * ���������O�t�@�C����������
1475 */
1476 const char *FLogGetFilename()
1477 {
1478 if (LogVar == NULL) {
1479 return NULL;
1480 }
1481 return LogVar->FullName;
1482 }
1483
1484 /**
1485 * ���O�_�C�A���O���J��
1486 * @param[in,out] info.filename �t�@�C���������l
1487 * OK���A�t�@�C�����A�s�v����������free()��������
1488 * @retval TRUE [ok] ����������
1489 * @retval FALSE �L�����Z��������
1490 */
1491 BOOL FLogOpenDialog(HINSTANCE hInst, HWND hWnd, FLogDlgInfo_t *info)
1492 {
1493 LogDlgWork_t *work = (LogDlgWork_t *)calloc(sizeof(LogDlgWork_t), 1);
1494 char *filenameA = ToCharW(info->filename);
1495 char *srcfnameA = FLogGetLogFilename(filenameA);
1496 wchar_t *srcfnameW = ToWcharA(srcfnameA);
1497 free(filenameA);
1498 free(srcfnameA);
1499 work->info = info;
1500 work->info->filename = srcfnameW;
1501 work->pts = &ts;
1502 INT_PTR ret = TTDialogBoxParam(
1503 hInst, MAKEINTRESOURCE(IDD_LOGDLG),
1504 hWnd, LogFnHook, (LPARAM)work);
1505 free(srcfnameW);
1506 free(work);
1507 return ret == IDOK ? TRUE : FALSE;
1508 }
1509
1510 /**
1511 * ���O�t�@�C����������
1512 * ���O�t�@�C�����p���C�����s��
1513 * - strftime() ���������t�W�J
1514 * - �������������O�t�@�C���t�H���_������
1515 * - �z�X�g��,�|�[�g�����W�J
1516 *
1517 * @param[in] log_filename �t�@�C����(����/��������������ok)
1518 * NULL�������f�t�H���g�t�@�C����������
1519 * strftime�`��ok
1520 * @return �t���p�X�t�@�C����
1521 * �s�v���������� free() ��������
1522 */
1523 char *FLogGetLogFilename(const char *log_filename)
1524 {
1525 // �t�H���_
1526 char FileDirExpanded[MAX_PATH];
1527 char *logdir;
1528 if (strlen(ts.LogDefaultPath) > 0) {
1529 logdir = ts.LogDefaultPath;
1530 }
1531 else if (strlen(ts.FileDir) > 0) {
1532 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1533 logdir = FileDirExpanded;
1534 }
1535 else {
1536 logdir = ts.HomeDir;
1537 }
1538
1539 // ���������t�@�C����
1540 char base_name[MAX_PATH];
1541 if (log_filename == NULL) {
1542 strncpy_s(base_name, _countof(base_name), ts.LogDefaultName, _TRUNCATE);
1543 }
1544 else {
1545 strncpy_s(base_name, _countof(base_name), log_filename, _TRUNCATE);
1546 }
1547
1548 // �t���p�X��
1549 char full_path[MAX_PATH];
1550 ConvFName(logdir, base_name, sizeof(base_name), "", full_path, sizeof(full_path));
1551 ParseStrftimeFileName(full_path, sizeof(full_path));
1552 ConvertLogname(full_path, sizeof(full_path));
1553
1554 return _strdup(full_path);
1555 }
1556
1557 BOOL FLogIsPause()
1558 {
1559 return ((cv.FilePause & OpLog) !=0);
1560 }
1561
1562 void FLogWindow(int nCmdShow)
1563 {
1564 if (FLogDlg == NULL)
1565 return;
1566
1567 HWND HWndLog = FLogDlg->m_hWnd;
1568 ShowWindow(HWndLog, nCmdShow);
1569 if (nCmdShow == SW_RESTORE) {
1570 // �g���X�^�C�� WS_EX_NOACTIVATE ��������������
1571 SetForegroundWindow(HWndLog);
1572 }
1573 }
1574
1575 void FLogShowDlg(void)
1576 {
1577 ShowFTDlg(OpLog);
1578 }

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