Develop and Download Open Source Software

Browse Subversion Repository

Diff of /trunk/teraterm/teraterm/filesys_log.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 8822 by zmatsuo, Thu Jul 2 15:41:37 2020 UTC revision 8852 by zmatsuo, Mon Jul 13 15:31:46 2020 UTC
# Line 31  Line 31 
31  #include <stdio.h>  #include <stdio.h>
32  #include <io.h>  #include <io.h>
33  #include <process.h>  #include <process.h>
34    #include <windows.h>
35    #include <htmlhelp.h>
36    #include <assert.h>
37    
38  #include "teraterm.h"  #include "teraterm.h"
39  #include "tttypes.h"  #include "tttypes.h"
40  #include "ttftypes.h"  #include "ttftypes.h"
 #include "tt_res.h"  
41  #include "ftdlg.h"  #include "ftdlg.h"
42  #include "protodlg.h"  #include "protodlg.h"
43  #include "ttwinman.h"  #include "ttwinman.h"
# Line 46  Line 48 
48  #include "dlglib.h"  #include "dlglib.h"
49  #include "vtterm.h"  #include "vtterm.h"
50  #include "win16api.h"  #include "win16api.h"
   
 #include "filesys.h"  
51  #include "ftlib.h"  #include "ftlib.h"
   
52  #include "buffer.h"  #include "buffer.h"
53    #include "helpid.h"
54    #include "layer_for_unicode.h"
55    
56  #include <io.h>  #include "filesys.h"
57  #include <process.h>  #include "tt_res.h"
58    #include "filesys_log_res.h"
59    
60  #define FS_BRACKET_NONE  0  #define FS_BRACKET_NONE  0
61  #define FS_BRACKET_START 1  #define FS_BRACKET_START 1
62  #define FS_BRACKET_END   2  #define FS_BRACKET_END   2
63    
64  PFileVar LogVar = NULL;  static PFileVar LogVar = NULL;
65  PFileVar SendVar = NULL;  PFileVar SendVar = NULL;
66  PFileVar FileVar = NULL;  PFileVar FileVar = NULL;
67  static PCHAR ProtoVar = NULL;  static PCHAR ProtoVar = NULL;
# Line 93  static HMODULE HTTFILE = NULL; Line 95  static HMODULE HTTFILE = NULL;
95  static int TTFILECount = 0;  static int TTFILECount = 0;
96    
97  PGetSetupFname GetSetupFname;  PGetSetupFname GetSetupFname;
98  PGetTransFname GetTransFname;  static PGetTransFname GetTransFname;
99  PGetMultiFname GetMultiFname;  PGetMultiFname GetMultiFname;
100  PGetGetFname GetGetFname;  PGetGetFname GetGetFname;
101  PSetFileVar SetFileVar;  PSetFileVar SetFileVar;
# Line 350  void FreeFileVar(PFileVar *fv) Line 352  void FreeFileVar(PFileVar *fv)
352          }          }
353  }  }
354    
355  // &h をホスト名に置換 (2007.5.14)  /**
356  // &p をTCPポート番号に置換 (2009.6.12)   *      ファイル名文字列の置き換え
357  void ConvertLogname(char *c, int destlen)   *              &h      ホスト名に置換 (2007.5.14)
358     *              &p      TCPポート番号に置換 (2009.6.12)
359     *              &u      ログオン中のユーザ名
360     */
361    static void ConvertLogname(char *c, int destlen)
362  {  {
363          char buf[MAXPATHLEN], buf2[MAXPATHLEN], *p = c;          char buf[MAXPATHLEN], buf2[MAXPATHLEN], *p = c;
364          char tmphost[1024];          char tmphost[1024];
# Line 410  void ConvertLogname(char *c, int destlen Line 416  void ConvertLogname(char *c, int destlen
416          strncpy_s(c, destlen, buf, _TRUNCATE);          strncpy_s(c, destlen, buf, _TRUNCATE);
417  }  }
418    
419  void FixLogOption()  static void FixLogOption()
420  {  {
421          if (ts.LogBinary) {          if (ts.LogBinary) {
422                  ts.LogTypePlainText = false;                  ts.LogTypePlainText = false;
# Line 423  void FixLogOption() Line 429  void FixLogOption()
429  static void CloseFileSync(PFileVar ptr)  static void CloseFileSync(PFileVar ptr)
430  {  {
431          BOOL ret;          BOOL ret;
         DWORD code;  
432    
433          if (!ptr->FileOpen)          if (!ptr->FileOpen)
434                  return;                  return;
# Line 436  static void CloseFileSync(PFileVar ptr) Line 441  static void CloseFileSync(PFileVar ptr)
441                          WaitForSingleObject(ptr->LogThread, INFINITE);                          WaitForSingleObject(ptr->LogThread, INFINITE);
442                  }                  }
443                  else {                  else {
444                          code = GetLastError();                          //DWORD code = GetLastError();
445                  }                  }
446                  CloseHandle(ptr->LogThread);                  CloseHandle(ptr->LogThread);
447                  ptr->LogThread = INVALID_HANDLE_VALUE;                  ptr->LogThread = INVALID_HANDLE_VALUE;
# Line 480  end: Line 485  end:
485          return (0);          return (0);
486  }  }
487    
488    /**
489  BOOL LogStart()   *      ダイアログの内容を ts に書き戻し
490  {   *
491          LONG Option;   *      TODO
492          char *logdir;   *              ダイアログで設定した値は一時的なもので
493          unsigned tid;   *              設定を上書きするのは良くないのではないだろうか?
494          DWORD ofs, size, written_size;   */
495          char buf[512];  static void SetLogFlags(HWND Dialog)
496          const char *crlf = "\r\n";  {
497          DWORD crlf_len = 2;          WORD BinFlag, val;
498          char FileDirExpanded[MAX_PATH];  
499            GetRB(Dialog, &BinFlag, IDC_FOPTBIN, IDC_FOPTBIN);
500          if ((FileLog) || (BinLog)) return FALSE;          ts.LogBinary = BinFlag;
501    
502          if (! LoadTTFILE()) return FALSE;          GetRB(Dialog, &val, IDC_FOPTAPPEND, IDC_FOPTAPPEND);
503          if (! NewFileVar(&LogVar))          ts.Append = val;
504          {  
505                  FreeTTFILE();          if (!BinFlag) {
506                  return FALSE;                  GetRB(Dialog, &val, IDC_PLAINTEXT, IDC_PLAINTEXT);
507                    ts.LogTypePlainText = val;
508    
509                    GetRB(Dialog, &val, IDC_TIMESTAMP, IDC_TIMESTAMP);
510                    ts.LogTimestamp = val;
511            }
512    
513            GetRB(Dialog, &val, IDC_HIDEDIALOG, IDC_HIDEDIALOG);
514            ts.LogHideDialog = val;
515    
516            GetRB(Dialog, &val, IDC_ALLBUFF_INFIRST, IDC_ALLBUFF_INFIRST);
517            ts.LogAllBuffIncludedInFirst = val;
518    
519            ts.LogTimestampType = (GetCurSel(Dialog, IDC_TIMESTAMPTYPE) - 1);
520    }
521    
522    /**
523     *      ログファイルチェック
524     *
525     *      @param[in]      filename
526     *      @param[out]     exist   TURE/FALSE
527     *      @param[out]     bom             0       no BOM (or file not exist)
528     *                                              1       UTF-8
529     *                                              2       UTF-16LE
530     *                                              3       UTF-16BE
531     */
532    static void CheckLogFile(const char *filename, BOOL *exist, int *bom)
533    {
534            // ファイルが存在する?
535            DWORD logdir = GetFileAttributes(filename);
536            if ((logdir != INVALID_FILE_ATTRIBUTES) && ((logdir & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
537                    // ファイルがあった , アペンドするつもり
538                    *exist = TRUE;
539    
540                    // BOM有り/無しチェック
541                    FILE *fp = fopen(filename, "rb");
542                    unsigned char tmp[4];
543                    size_t l = fread(tmp, 1, sizeof(tmp), fp);
544                    fclose(fp);
545                    if (l < 2) {
546                            *bom = 0;
547                    } else if (l >= 2 && tmp[0] == 0xff && tmp[1] == 0xfe) {
548                            // UTF-16LE
549                            *bom = 2;
550                    } else if (l >= 2 && tmp[0] == 0xfe && tmp[1] == 0xff) {
551                            // UTF-16BE
552                            *bom = 3;
553                    } else if (l >= 3 && tmp[0] == 0xef && tmp[1] == 0xbb && tmp[2] == 0xbf) {
554                            // UTF-8
555                            *bom = 1;
556                    } else {
557                            *bom = 0;
558                    }
559          }          }
560          LogVar->OpId = OpLog;          else {
561                    // ファイルがない、新規
562          if (strlen(ts.LogDefaultPath) > 0) {                  *exist = FALSE;
563                  logdir = ts.LogDefaultPath;                  *bom = 0;
564          }          }
565          else if (strlen(ts.FileDir) > 0) {  }
566                  ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));  
567                  logdir = FileDirExpanded;  static void CheckLogFile(HWND Dialog, const char *filename)
568    {
569            BOOL exist;
570            int bom;
571            CheckLogFile(filename, &exist, &bom);
572            if (exist) {
573                    // ファイルが存在する -> アペンドするつもり?
574                    CheckDlgButton(Dialog, IDC_FOPTAPPEND, BST_CHECKED);
575                    if (bom != 0) {
576                            // BOM有り
577                            CheckDlgButton(Dialog, IDC_BOM, BST_CHECKED);
578                    }
579                    else {
580                            // BOMなし
581                            CheckDlgButton(Dialog, IDC_BOM, BST_UNCHECKED);
582                    }
583          }          }
584          else {          else {
585                  logdir = ts.HomeDir;                  // ファイルがない、新規
586                    CheckDlgButton(Dialog, IDC_FOPTAPPEND, BST_UNCHECKED);
587                    CheckDlgButton(Dialog, IDC_BOM, BST_CHECKED);
588          }          }
589    }
590    
591          if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0) {  typedef struct {
592                  Option = 0;          char *filename;
593            BOOL append;
594            BOOL bom;
595    } LogDlgData_t;
596    
597    static INT_PTR CALLBACK LogFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam)
598    {
599            static const DlgTextInfo TextInfos[] = {
600                    { 0, "DLG_TABSHEET_TITLE_LOG" },
601                    { IDC_FOPTBIN, "DLG_FOPT_BINARY" },
602                    { IDC_FOPTAPPEND, "DLG_FOPT_APPEND" },
603                    { IDC_PLAINTEXT, "DLG_FOPT_PLAIN" },
604                    { IDC_HIDEDIALOG, "DLG_FOPT_HIDEDIALOG" },
605                    { IDC_ALLBUFF_INFIRST, "DLG_FOPT_ALLBUFFINFIRST" },
606                    { IDC_TIMESTAMP, "DLG_FOPT_TIMESTAMP" },
607            };
608            static const I18nTextInfo timestamp_list[] = {
609                    { "DLG_FOPT_TIMESTAMP_LOCAL", L"Local Time" },
610                    { "DLG_FOPT_TIMESTAMP_UTC", L"UTC" },
611                    { "DLG_FOPT_TIMESTAMP_ELAPSED_LOGGING", L"Elapsed Time (Logging)" },
612                    { "DLG_FOPT_TIMESTAMP_ELAPSED_CONNECTION", L"Elapsed Time (Connection)" },
613            };
614            const char *UILanguageFile = ts.UILanguageFile;
615            LogDlgData_t *data = (LogDlgData_t *)GetWindowLongPtr(Dialog, DWLP_USER);
616    
617            if (Message ==  RegisterWindowMessage(HELPMSGSTRING)) {
618                    // コモンダイアログからのヘルプメッセージを付け替える
619                    Message = WM_COMMAND;
620                    wParam = IDHELP;
621            }
622            switch (Message) {
623            case WM_INITDIALOG: {
624                    data = (LogDlgData_t *)lParam;
625                    SetWindowLongPtr(Dialog, DWLP_USER, (LONG_PTR)data);
626                    ::DragAcceptFiles(Dialog, TRUE);
627    
628                    SetDlgTexts(Dialog, TextInfos, _countof(TextInfos), UILanguageFile);
629                    SetI18nList("Tera Term", Dialog, IDC_TIMESTAMPTYPE, timestamp_list, _countof(timestamp_list),
630                                            UILanguageFile, 0);
631    
632                    SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_ADDSTRING, 0, (LPARAM)"UTF-8");
633                    SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, 0, 0);
634    
635                    SetDlgItemTextA(Dialog, IDC_FOPT_FILENAME_EDIT, data->filename);
636                    free(data->filename);
637                    data->filename = NULL;
638    
639                    // Binary/Text チェックボックス
640                  if (ts.LogBinary) {                  if (ts.LogBinary) {
641                          Option |= LOGDLG_BINARY;                          SendDlgItemMessage(Dialog, IDC_FOPTBIN, BM_SETCHECK, BST_CHECKED, 0);
642                  }                  }
643                    else {
644                            SendDlgItemMessage(Dialog, IDC_FOPTTEXT, BM_SETCHECK, BST_CHECKED, 0);
645                    }
646    
647                    // Append チェックボックス
648                  if (ts.Append) {                  if (ts.Append) {
649                          Option |= LOGDLG_APPEND;                          SetRB(Dialog, 1, IDC_FOPTAPPEND, IDC_FOPTAPPEND);
650                  }                  }
651                  if (ts.LogTypePlainText) {  
652                          Option |= LOGDLG_PLAINTEXT;                  // Plain Text チェックボックス
653                    if (ts.LogBinary) {
654                            // Binaryフラグが有効なときはチェックできない
655                            DisableDlgItem(Dialog, IDC_PLAINTEXT, IDC_PLAINTEXT);
656                  }                  }
657                  if (ts.LogTimestamp) {                  else if (ts.LogTypePlainText) {
658                          Option |= LOGDLG_TIMESTAMP;                          SetRB(Dialog, 1, IDC_PLAINTEXT, IDC_PLAINTEXT);
659                  }                  }
660    
661                    // Hide dialogチェックボックス (2008.1.30 maya)
662                  if (ts.LogHideDialog) {                  if (ts.LogHideDialog) {
663                          Option |= LOGDLG_HIDEDIALOG;                          SetRB(Dialog, 1, IDC_HIDEDIALOG, IDC_HIDEDIALOG);
664                  }                  }
665    
666                    // Include screen bufferチェックボックス (2013.9.29 yutaka)
667                  if (ts.LogAllBuffIncludedInFirst) {                  if (ts.LogAllBuffIncludedInFirst) {
668                          Option |= LOGDLG_INCSCRBUFF;                          SetRB(Dialog, 1, IDC_ALLBUFF_INFIRST, IDC_ALLBUFF_INFIRST);
669                  }                  }
670    
671                  switch (ts.LogTimestampType) {                  // timestampチェックボックス (2006.7.23 maya)
672                  case TIMESTAMP_LOCAL:                  if (ts.LogBinary) {
673                          // nothing to do                          // Binaryフラグが有効なときはチェックできない
674                          break;                          DisableDlgItem(Dialog, IDC_TIMESTAMP, IDC_TIMESTAMP);
675                  case TIMESTAMP_UTC:                  }
676                          Option |= LOGDLG_UTC;                  else if (ts.LogTimestamp) {
677                          break;                          SetRB(Dialog, 1, IDC_TIMESTAMP, IDC_TIMESTAMP);
                 case TIMESTAMP_ELAPSED_LOGSTART:  
                         Option |= LOGDLG_ELAPSED;  
                         break;  
                 case TIMESTAMP_ELAPSED_CONNECTED:  
                         Option |= LOGDLG_ELAPSED | LOGDLG_ELAPSEDCON;  
                         break;  
                 default:  
                         // not reached  
                         break;  
678                  }                  }
679    
680                  // ログのデフォルトファイル名を設定 (2006.8.28 maya)                  // timestamp 種別
681                  strncat_s(LogVar->FullName, sizeof(LogVar->FullName), ts.LogDefaultName, _TRUNCATE);                  int tstype = ts.LogTimestampType == TIMESTAMP_LOCAL ? 0 :
682                  ParseStrftimeFileName(LogVar->FullName, sizeof(LogVar->FullName));                                  ts.LogTimestampType == TIMESTAMP_UTC ? 1 :
683                  ConvertLogname(LogVar->FullName, sizeof(LogVar->FullName));                                  ts.LogTimestampType == TIMESTAMP_ELAPSED_LOGSTART ? 2 :
684                                    ts.LogTimestampType == TIMESTAMP_ELAPSED_CONNECTED ? 3 : 0;
685                  strncpy_s(LogVar->LogDefaultPath, sizeof(LogVar->LogDefaultPath), ts.LogDefaultPath, _TRUNCATE);                  SendDlgItemMessage(Dialog, IDC_TIMESTAMPTYPE, CB_SETCURSEL, tstype, 0);
686                  if (! (*GetTransFname)(LogVar, logdir, GTF_LOG, &Option)) {                  if (ts.LogBinary || !ts.LogTimestamp) {
687                          FreeFileVar(&LogVar);                          DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
                         FreeTTFILE();  
                         return FALSE;  
688                  }                  }
689    
690                  ts.LogBinary = CheckFlag(Option, LOGDLG_BINARY);                  CenterWindow(Dialog, GetParent(Dialog));
691                          CheckFlag(Option, LOGDLG_BINARY);  
692                  ts.Append =                  return TRUE;
693                          CheckFlag(Option, LOGDLG_APPEND);          }
694                  ts.LogTypePlainText =  
695                          CheckFlag(Option, LOGDLG_PLAINTEXT);          case WM_COMMAND:
696                  ts.LogTimestamp =                  switch (LOWORD(wParam)) {
697                          CheckFlag(Option, LOGDLG_TIMESTAMP);                  case IDOK: {
698                  ts.LogHideDialog =                          char filename[MAX_PATH];
699                          CheckFlag(Option, LOGDLG_HIDEDIALOG);                          GetDlgItemTextA(Dialog, IDC_FOPT_FILENAME_EDIT, filename, _countof(filename));
700                  ts.LogAllBuffIncludedInFirst =                          data->filename = _strdup(filename);
701                          CheckFlag(Option, LOGDLG_INCSCRBUFF);                          data->append = IsDlgButtonChecked(Dialog, IDC_FOPTAPPEND) == BST_CHECKED;
702                            data->bom = IsDlgButtonChecked(Dialog, IDC_BOM) == BST_CHECKED;
703                  if (Option & LOGDLG_ELAPSED) {                          SetLogFlags(Dialog);
704                          // 経過時間                          EndDialog(Dialog, IDOK);
705                          if (Option & LOGDLG_ELAPSEDCON) {                          break;
706                                  ts.LogTimestampType = TIMESTAMP_ELAPSED_CONNECTED;                  }
707                    case IDCANCEL:
708                            EndDialog(Dialog, IDCANCEL);
709                            break;
710                    case IDHELP:
711                            OpenHelp(HH_HELP_CONTEXT, HlpFileLog, ts.UILanguageFile);
712                            break;
713                    case IDC_FOPT_FILENAME_BUTTON: {
714                            /* save current dir */
715                            wchar_t curdir[MAXPATHLEN];
716                            _GetCurrentDirectoryW(_countof(curdir), curdir);
717    
718                            char fname[MAX_PATH];
719                            GetDlgItemTextA(Dialog, IDC_FOPT_FILENAME_EDIT, fname, _countof(fname));
720    
721                            char FNFilter[128*3];
722                            get_lang_msg("FILEDLG_ALL_FILTER", FNFilter, sizeof(FNFilter), "All(*.*)\\0*.*\\0\\0", UILanguageFile);
723    
724                            char caption[MAX_PATH];
725                            char uimsg[MAX_UIMSG];
726                            get_lang_msg("FILEDLG_TRANS_TITLE_LOG", uimsg, sizeof(uimsg), TitLog, UILanguageFile);
727                            strncpy_s(caption, sizeof(caption),"Tera Term: ", _TRUNCATE);
728                            strncat_s(caption, sizeof(caption), uimsg, _TRUNCATE);
729    
730                            OPENFILENAME ofn = {};
731                            ofn.lStructSize = get_OPENFILENAME_SIZEA();
732                            //ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
733                            ofn.Flags |= OFN_EXPLORER | OFN_ENABLESIZING;
734                            ofn.Flags |= OFN_SHOWHELP;
735                            ofn.Flags |= OFN_NOCHANGEDIR;           // うまく動作しない環境もあるようだ
736                            ofn.hwndOwner = Dialog;
737                            ofn.lpstrFilter = FNFilter;
738                            ofn.nFilterIndex = 1;
739                            ofn.lpstrFile = fname;
740                            ofn.nMaxFile = sizeof(fname);
741                            ofn.lpstrTitle = caption;
742                            BOOL Ok = GetSaveFileName(&ofn);
743                            if (Ok) {
744                                    SetDlgItemTextA(Dialog, IDC_FOPT_FILENAME_EDIT, fname);
745                            }
746    
747                            /* restore dir */
748                            _SetCurrentDirectoryW(curdir);
749    
750                            break;
751                    }
752                    case IDC_FOPTBIN:
753                            DisableDlgItem(Dialog, IDC_PLAINTEXT, IDC_TIMESTAMP);
754                            DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
755                            EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), FALSE);
756                            break;
757                    case IDC_FOPTTEXT:
758                            EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), TRUE);
759                            EnableDlgItem(Dialog, IDC_PLAINTEXT, IDC_TIMESTAMP);
760                            // FALLTHROUGH -- BinFlag が off の時は Timestamp 種別の有効/無効を設定する
761                    case IDC_TIMESTAMP:
762                            if (IsDlgButtonChecked(Dialog, IDC_TIMESTAMP) == BST_CHECKED) {
763                                    EnableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
764                          }                          }
765                          else {                          else {
766                                  ts.LogTimestampType = TIMESTAMP_ELAPSED_LOGSTART;                                  DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
767                          }                          }
768                  }                          break;
769                  else {                  case IDC_FOPT_FILENAME_EDIT:
770                          // 日時形式                          if (HIWORD(wParam) == EN_CHANGE){
771                          if (Option & LOGDLG_UTC) {                                  char filename[MAX_PATH];
772                                  ts.LogTimestampType = TIMESTAMP_UTC;                                  GetDlgItemTextA(Dialog, IDC_FOPT_FILENAME_EDIT, filename, _countof(filename));
773                          }                                  CheckLogFile(Dialog, filename);
                         else {  
                                 ts.LogTimestampType = TIMESTAMP_LOCAL;  
774                          }                          }
775                            break;
776                  }                  }
777                    break;
778            case WM_DROPFILES: {
779                    // 複数ドロップされても最初の1つだけを扱う
780                    HDROP hDrop = (HDROP)wParam;
781                    const UINT len = _DragQueryFileW(hDrop, 0, NULL, 0);
782                    if (len == 0) {
783                            DragFinish(hDrop);
784                            return TRUE;
785                    }
786                    wchar_t *filename = (wchar_t *)malloc(sizeof(wchar_t) * (len + 1));
787                    _DragQueryFileW(hDrop, 0, filename, len + 1);
788                    filename[len] = '\0';
789                    _SetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, filename);
790                    SendDlgItemMessage(Dialog, IDC_FOPT_FILENAME_EDIT, EM_SETSEL, len, len);
791                    free(filename);
792                    DragFinish(hDrop);
793                    return TRUE;
794          }          }
795          else {          }
796                  // LogVar->DirLen = 0 だとここに来る          return FALSE;
797                  // フルパス・相対パスともに LogVar->FullName に入れておく必要がある  }
                 char FileName[MAX_PATH];  
798    
799                  // フルパス化  static BOOL LogStart()
800                  strncpy_s(FileName, sizeof(FileName), LogVar->FullName, _TRUNCATE);  {
801                  ConvFName(logdir, FileName, sizeof(FileName), "", LogVar->FullName, sizeof(LogVar->FullName));          unsigned tid;
802    
803                  ParseStrftimeFileName(LogVar->FullName, sizeof(LogVar->FullName));          if ((FileLog) || (BinLog)) return FALSE;
                 ConvertLogname(LogVar->FullName, sizeof(LogVar->FullName));  
804    
805                  (*SetFileVar)(LogVar);          assert(LogVar != NULL);
806    
807                  FixLogOption();          if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0) {
808                    // ファイル名が設定されていない
809                    return FALSE;
810          }          }
811    
812            if (! LoadTTFILE()) return FALSE;
813    
814            LogVar->OpId = OpLog;
815            (*SetFileVar)(LogVar);
816            FixLogOption();
817    
818          if (ts.LogBinary > 0)          if (ts.LogBinary > 0)
819          {          {
820                  BinLog = TRUE;                  BinLog = TRUE;
# Line 690  BOOL LogStart() Line 892  BOOL LogStart()
892          // 最初のファイルが設定したサイズでローテートしない問題の修正。          // 最初のファイルが設定したサイズでローテートしない問題の修正。
893          // (2016.4.9 yutaka)          // (2016.4.9 yutaka)
894          if (LogVar->RotateMode != ROTATE_NONE) {          if (LogVar->RotateMode != ROTATE_NONE) {
895                  size = GetFileSize(LogVar->FileHandle, NULL);                  DWORD size = GetFileSize(LogVar->FileHandle, NULL);
896                  if (size != -1)                  if (size != -1)
897                          LogVar->ByteCount = size;                          LogVar->ByteCount = size;
898          }          }
# Line 721  BOOL LogStart() Line 923  BOOL LogStart()
923          // ログ採取を開始する。          // ログ採取を開始する。
924          // (2013.9.29 yutaka)          // (2013.9.29 yutaka)
925          if (ts.LogAllBuffIncludedInFirst) {          if (ts.LogAllBuffIncludedInFirst) {
926                    DWORD ofs, size, written_size;
927                    char buf[512];
928                    const char *crlf = "\r\n";
929                    DWORD crlf_len = 2;
930                  for (ofs = 0 ;  ; ofs++ ) {                  for (ofs = 0 ;  ; ofs++ ) {
931                          // 1つの行を取得する。文字だけなので、エスケープシーケンスは含まれない。                          // 1つの行を取得する。文字だけなので、エスケープシーケンスは含まれない。
932                          size = BuffGetAnyLineData(ofs, buf, sizeof(buf));                          size = BuffGetAnyLineData(ofs, buf, sizeof(buf));
# Line 820  static inline void logfile_unlock(void) Line 1026  static inline void logfile_unlock(void)
1026  }  }
1027    
1028   // コメントをログへ追加する   // コメントをログへ追加する
1029  void CommentLogToFile(char *buf, int size)  static void CommentLogToFile(char *buf, int size)
1030  {  {
1031          DWORD wrote;          DWORD wrote;
1032    
# Line 1469  BOOL OpenProtoDlg(PFileVar fv, int IdPro Line 1675  BOOL OpenProtoDlg(PFileVar fv, int IdPro
1675                  case PROTO_QV:                  case PROTO_QV:
1676                          vsize = sizeof(TQVVar);                          vsize = sizeof(TQVVar);
1677                          break;                          break;
1678                    default:
1679                            vsize = 0;
1680                            assert(FALSE);
1681                            break;
1682          }          }
1683          ProtoVar = (PCHAR)malloc(vsize);          ProtoVar = (PCHAR)malloc(vsize);
1684          if (ProtoVar==NULL)          if (ProtoVar==NULL)
# Line 1910  void QVStart(int mode) Line 2120  void QVStart(int mode)
2120          if (! OpenProtoDlg(FileVar,PROTO_QV,mode,0,0))          if (! OpenProtoDlg(FileVar,PROTO_QV,mode,0,0))
2121                  ProtoEnd();                  ProtoEnd();
2122  }  }
2123    
2124    /**
2125     *      ログローテートの設定
2126     *      ログのサイズが<size>バイトを超えていれば、ローテーションするよう設定する
2127     */
2128    void LogRotateSize(size_t size)
2129    {
2130            if (LogVar == NULL) {
2131                    return;
2132            }
2133            LogVar->RotateMode = ROTATE_SIZE;
2134            LogVar->RotateSize = size;
2135    }
2136    
2137    /**
2138     *      ログローテートの設定
2139     *      ログファイルの世代を設定する
2140     */
2141    void LogRotateRotate(int step)
2142    {
2143            if (LogVar == NULL) {
2144                    return;
2145            }
2146            LogVar->RotateStep = step;
2147    }
2148    
2149    /**
2150     *      ログローテートの設定
2151     *      ローテーションを停止
2152     */
2153    void LogRotateHalt(void)
2154    {
2155            if (LogVar == NULL) {
2156                    return;
2157            }
2158            LogVar->RotateMode = ROTATE_NONE;
2159            LogVar->RotateSize = 0;
2160            LogVar->RotateStep = 0;
2161    }
2162    
2163    static INT_PTR CALLBACK OnCommentDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp)
2164    {
2165            static const DlgTextInfo TextInfos[] = {
2166                    { 0, "DLG_COMMENT_TITLE" },
2167                    { IDOK, "BTN_OK" }
2168            };
2169            char buf[256];
2170            UINT ret;
2171    
2172            switch (msg) {
2173                    case WM_INITDIALOG:
2174                            //SetDlgItemText(hDlgWnd, IDC_EDIT_COMMENT, "サンプル");
2175                            // エディットコントロールにフォーカスをあてる
2176                            SetFocus(GetDlgItem(hDlgWnd, IDC_EDIT_COMMENT));
2177                            SetDlgTexts(hDlgWnd, TextInfos, _countof(TextInfos), ts.UILanguageFile);
2178                            return FALSE;
2179    
2180                    case WM_COMMAND:
2181                            switch (LOWORD(wp)) {
2182                                    case IDOK:
2183                                            memset(buf, 0, sizeof(buf));
2184                                            ret = GetDlgItemTextA(hDlgWnd, IDC_EDIT_COMMENT, buf, sizeof(buf) - 1);
2185                                            if (ret > 0) { // テキスト取得成功
2186                                                    //buf[sizeof(buf) - 1] = '\0';  // null-terminate
2187                                                    CommentLogToFile(buf, ret);
2188                                            }
2189                                            TTEndDialog(hDlgWnd, IDOK);
2190                                            break;
2191                                    default:
2192                                            return FALSE;
2193                            }
2194                            break;
2195                    case WM_CLOSE:
2196                            TTEndDialog(hDlgWnd, 0);
2197                            return TRUE;
2198    
2199                    default:
2200                            return FALSE;
2201            }
2202            return TRUE;
2203    }
2204    
2205    void LogAddCommentDlg(HINSTANCE hInst, HWND hWnd)
2206    {
2207            // ログファイルへコメントを追加する (2004.8.6 yutaka)
2208            TTDialogBox(hInst, MAKEINTRESOURCE(IDD_COMMENT_DIALOG),
2209                                    HVTWin, OnCommentDlgProc);
2210    }
2211    
2212    void LogClose()
2213    {
2214            if (LogVar != NULL)
2215                    FileTransEnd(OpLog);
2216    }
2217    
2218    BOOL LogOpen(const char *fname)
2219    {
2220            BOOL ret;
2221    
2222            if ((LogVar==NULL) && !NewFileVar(&LogVar)) {
2223                    return FALSE;
2224            }
2225    
2226            LogVar->DirLen = 0;
2227            LogVar->NoMsg = TRUE;
2228            strncpy_s(LogVar->FullName, sizeof(LogVar->FullName), fname, _TRUNCATE);
2229            ret = LogStart();
2230            return ret;
2231    }
2232    
2233    BOOL LogIsOpend()
2234    {
2235            // LogVar->FileOpen
2236            return LogVar != NULL;
2237    }
2238    
2239    void LogWriteStr(const char *str)
2240    {
2241            if (LogVar != NULL)
2242            {
2243                    DWORD wrote;
2244                    size_t len = strlen(str);
2245                    WriteFile(LogVar->FileHandle, str, len, &wrote, NULL);
2246                    LogVar->ByteCount =
2247                            LogVar->ByteCount + len;
2248                    FLogRefreshNum();
2249            }
2250    }
2251    
2252    void LogInfo(char *param_ptr, size_t param_len)
2253    {
2254            if (LogVar) {
2255                    param_ptr[0] = '0'
2256                            + (ts.LogBinary != 0)
2257                            + ((ts.Append != 0) << 1)
2258                            + ((ts.LogTypePlainText != 0) << 2)
2259                            + ((ts.LogTimestamp != 0) << 3)
2260                            + ((ts.LogHideDialog != 0) << 4);
2261                    strncpy_s(param_ptr + 1, param_len - 1, LogVar->FullName, _TRUNCATE);
2262            }
2263            else {
2264                    param_ptr[0] = '0' - 1;
2265                    param_ptr[1] = 0;
2266            }
2267    }
2268    
2269    /**
2270     *      現在のログファイル名を取得
2271     */
2272    const char *LogGetFilename()
2273    {
2274            if (LogVar == NULL) {
2275                    return NULL;
2276            }
2277            return LogVar->FullName;
2278    }
2279    
2280    /**
2281     *      ログダイアログを開く
2282     *      @retval TRUE    [ok] が押された
2283     *      @retval FALSE   キャンセルされた
2284     *      @param[in,out]  filename        OK時、ファイル名、不要になったらfree()すること
2285     */
2286    BOOL LogOpenDialog(char **filename)
2287    {
2288            LogDlgData_t *data = (LogDlgData_t *)calloc(sizeof(LogDlgData_t), 1);
2289            data->filename = LogGetLogFilename(NULL);
2290            INT_PTR ret = TTDialogBoxParam(
2291                    hInst, MAKEINTRESOURCE(IDD_LOGDLG),
2292                    HVTWin, LogFnHook, (LPARAM)data);
2293            if (ret == IDOK) {
2294                    *filename = data->filename;
2295            }
2296            free(data);
2297            return ret == IDOK ? TRUE : FALSE;
2298    }
2299    
2300    /**
2301     *      ログファイル名を取得
2302     *      ログファイル名用の修飾を行う
2303     *      - strftime() と同じ日付展開
2304     *      - 設定されたログファイルフォルダを追加
2305     *      - ホスト名,ポート番号展開
2306     *
2307     *      @param[in]      log_filename    ファイル名(相対/絶対どちらでもok)
2308     *                                                              NULLの場合デフォルトファイル名となる
2309     *                                                              strftime形式ok
2310     *      @return                                         フルパスファイル名
2311     *                                                              不要になったら free() すること
2312     */
2313    char *LogGetLogFilename(const char *log_filename)
2314    {
2315            // フォルダ
2316            char FileDirExpanded[MAX_PATH];
2317            char *logdir;
2318            if (strlen(ts.LogDefaultPath) > 0) {
2319                    logdir = ts.LogDefaultPath;
2320            }
2321            else if (strlen(ts.FileDir) > 0) {
2322                    ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
2323                    logdir = FileDirExpanded;
2324            }
2325            else {
2326                    logdir = ts.HomeDir;
2327            }
2328    
2329            // 元となるファイル名
2330            char base_name[MAX_PATH];
2331            if (log_filename == NULL) {
2332                    strncpy_s(base_name, _countof(base_name), ts.LogDefaultName, _TRUNCATE);
2333            }
2334            else {
2335                    strncpy_s(base_name, _countof(base_name), log_filename, _TRUNCATE);
2336            }
2337    
2338            // フルパス化
2339            char full_path[MAX_PATH];
2340            ConvFName(logdir, base_name, sizeof(base_name), "", full_path, sizeof(full_path));
2341            ParseStrftimeFileName(full_path, sizeof(full_path));
2342            ConvertLogname(full_path, sizeof(full_path));
2343    
2344            return _strdup(full_path);
2345    }

Legend:
Removed from v.8822  
changed lines
  Added in v.8852

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