Develop and Download Open Source Software

Browse CVS Repository

Diff of /ttssh2/teraterm/source/teraterm/filesys.cpp

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

revision 1.1.1.1 by yutakakn, Mon Nov 15 14:43:41 2004 UTC revision 1.12 by yutakapon, Fri May 25 09:56:05 2007 UTC
# Line 64  PProtoCancel ProtoCancel; Line 64  PProtoCancel ProtoCancel;
64  #define IdProtoTimeOutProc 9  #define IdProtoTimeOutProc 9
65  #define IdProtoCancel    10  #define IdProtoCancel    10
66    
67    /*
68       Line Head flag for timestamping
69       2007.05.24 Gentaro
70    */
71    enum enumLineEnd {
72            Line_Other = 0,
73            Line_LineHead = 1,
74            Line_FileHead = 2,
75    };
76    
77    enum enumLineEnd eLineEnd = Line_LineHead;
78    
79  BOOL LoadTTFILE()  BOOL LoadTTFILE()
80  {  {
81    BOOL Err;    BOOL Err;
# Line 165  static PProtoDlg PtDlg = NULL; Line 177  static PProtoDlg PtDlg = NULL;
177  BOOL OpenFTDlg(PFileVar fv)  BOOL OpenFTDlg(PFileVar fv)
178  {  {
179    PFileTransDlg FTDlg;    PFileTransDlg FTDlg;
180    #ifdef I18N
181      HWND HFTDlg;
182    #endif
183    
184    FTDlg = new CFileTransDlg();    FTDlg = new CFileTransDlg();
185        
186    if (FTDlg!=NULL)    if (FTDlg!=NULL)
187    {    {
188    #ifdef I18N
189        FTDlg->Create(fv, &cv, &ts);
190    #else
191      FTDlg->Create(fv, &cv);      FTDlg->Create(fv, &cv);
192    #endif
193      FTDlg->RefreshNum();      FTDlg->RefreshNum();
194      if (fv->OpId == OpLog)      if (fv->OpId == OpLog)
195        FTDlg->ShowWindow(SW_MINIMIZE);        FTDlg->ShowWindow(SW_MINIMIZE);
# Line 181  BOOL OpenFTDlg(PFileVar fv) Line 200  BOOL OpenFTDlg(PFileVar fv)
200    else    else
201      SendDlg = FTDlg; /* File send */      SendDlg = FTDlg; /* File send */
202    
203    #ifdef I18N
204      HFTDlg=FTDlg->GetSafeHwnd();
205    
206      GetDlgItemText(HFTDlg, IDC_TRANS_FILENAME, ts.UIMsg, sizeof(ts.UIMsg));
207      get_lang_msg("DLG_FILETRANS_FILENAME", ts.UIMsg, ts.UILanguageFile);
208      SetDlgItemText(HFTDlg, IDC_TRANS_FILENAME, ts.UIMsg);
209      GetDlgItemText(HFTDlg, IDC_FULLPATH_LABEL, ts.UIMsg, sizeof(ts.UIMsg));
210      get_lang_msg("DLG_FILETRANS_FULLPATH", ts.UIMsg, ts.UILanguageFile);
211      SetDlgItemText(HFTDlg, IDC_FULLPATH_LABEL, ts.UIMsg);
212      GetDlgItemText(HFTDlg, IDC_TRANS_TRANS, ts.UIMsg, sizeof(ts.UIMsg));
213      get_lang_msg("DLG_FILETRANS_TRNAS", ts.UIMsg, ts.UILanguageFile);
214      SetDlgItemText(HFTDlg, IDC_TRANS_TRANS, ts.UIMsg);
215      GetDlgItemText(HFTDlg, IDCANCEL, ts.UIMsg, sizeof(ts.UIMsg));
216      get_lang_msg("BTN_CANCEL", ts.UIMsg, ts.UILanguageFile);
217      SetDlgItemText(HFTDlg, IDCANCEL, ts.UIMsg);
218      GetDlgItemText(HFTDlg, IDC_TRANSPAUSESTART, ts.UIMsg, sizeof(ts.UIMsg));
219      get_lang_msg("DLG_FILETRANS_PAUSE", ts.UIMsg, ts.UILanguageFile);
220      SetDlgItemText(HFTDlg, IDC_TRANSPAUSESTART, ts.UIMsg);
221      GetDlgItemText(HFTDlg, IDC_TRANSHELP, ts.UIMsg, sizeof(ts.UIMsg));
222      get_lang_msg("BTN_HELP", ts.UIMsg, ts.UILanguageFile);
223      SetDlgItemText(HFTDlg, IDC_TRANSHELP, ts.UIMsg);
224    #endif
225    
226    return (FTDlg!=NULL);    return (FTDlg!=NULL);
227  }  }
228    
# Line 221  void FreeFileVar(PFileVar *fv) Line 263  void FreeFileVar(PFileVar *fv)
263    }    }
264  }  }
265    
266    // &h をホスト名に置換 (2007.5.14)
267    void ConvertLogname(char *c)
268    {
269      char buf[MAXPATHLEN], buf2[MAXPATHLEN], *p = c;
270    
271      memset(buf, 0, sizeof(buf));
272    
273      while(*p != '\0') {
274        if (*p == '&' && *(p+1) != '\0') {
275          switch (*(p+1)) {
276            case 'h':
277              if (cv.Open) {
278                if (cv.PortType == IdTCPIP) {
279                  _snprintf(buf2, sizeof(buf2), "%s%s", buf, ts.HostName);
280                  strncpy(buf, buf2, sizeof(buf)-strlen(buf)-1);
281                }
282                else if (cv.PortType == IdSerial) {
283                  _snprintf(buf2, sizeof(buf2), "%sCOM%d", buf, ts.ComPort);
284                  strncpy(buf, buf2, sizeof(buf)-strlen(buf)-1);
285                }
286              }
287              break;
288            default:
289              if (strlen(buf) < sizeof(buf)-3) {
290                strncat(buf, p, 2);
291              }
292          }
293          p++;
294        }
295        else {
296              if (strlen(buf) < sizeof(buf)-2) {
297                strncat(buf, p, 1);
298              }
299        }
300        p++;
301      }
302      strcpy(c, buf);
303    }
304    
305  extern "C" {  extern "C" {
306  void LogStart()  void LogStart()
307  {  {
308    LONG Option;          LONG Option;
309    
310    if ((FileLog) || (BinLog)) return;          if ((FileLog) || (BinLog)) return;
311    
312    if (! LoadTTFILE()) return;          if (! LoadTTFILE()) return;
313    if (! NewFileVar(&LogVar))          if (! NewFileVar(&LogVar))
314    {          {
315      FreeTTFILE();                  FreeTTFILE();
316      return;                  return;
317    }          }
318    LogVar->OpId = OpLog;          LogVar->OpId = OpLog;
319    
320    if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0)          if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0)
321    {          {
322      Option = MAKELONG(ts.TransBin,ts.Append);                  // LOWORD
323      if (! (*GetTransFname)(LogVar, ts.FileDir, GTF_LOG, &Option))                  // 0x0001 = Binary
324      {                  // HIWORD
325        FreeFileVar(&LogVar);                  // 0x0001 = Append
326        FreeTTFILE();                  // 0x1000 = plain text (2005.2.20 yutaka)
327        return;                  // 0x2000 = timestamp (2006.7.23 maya)
328      }                  // teraterm.iniの設定を見てからデフォルトオプションを決める。(2005.5.7 yutaka)
329      ts.TransBin = LOWORD(Option);                  Option = MAKELONG(ts.TransBin,ts.Append |
330      ts.Append = HIWORD(Option);                                                    (0x1000 * ts.LogTypePlainText) |
331    }                                                    (0x2000 * ts.LogTimestamp));
332    else  
333      (*SetFileVar)(LogVar);                  // ログのデフォルトファイル名を設定 (2006.8.28 maya)
334                    strncat(LogVar->FullName, ts.LogDefaultName, sizeof(LogVar->FullName));
335                    ParseStrftimeFileName(LogVar->FullName);
336    
337    if (ts.TransBin > 0)                  // &h をホスト名に置換 (2007.5.14)
338    {                  ConvertLogname(LogVar->FullName);
     BinLog = TRUE;  
     FileLog = FALSE;  
     if (! CreateBinBuf())  
     {  
       FileTransEnd(OpLog);  
       return;  
     }  
   }  
   else {  
     BinLog = FALSE;  
     FileLog = TRUE;  
     if (! CreateLogBuf())  
     {  
       FileTransEnd(OpLog);  
       return;  
     }  
   }  
   cv.LStart = cv.LogPtr;  
   cv.LCount = 0;  
339    
340    HelpId = HlpFileLog;                  if (! (*GetTransFname)(LogVar, ts.FileDir, GTF_LOG, &Option))
341    if (ts.Append > 0)                  {
342    {                          FreeFileVar(&LogVar);
343      LogVar->FileHandle = _lopen(LogVar->FullName,OF_WRITE);                          FreeTTFILE();
344      if (LogVar->FileHandle>0)                          return;
345        _llseek(LogVar->FileHandle,0,2);                  }
346      else                  ts.TransBin = LOWORD(Option);
347        LogVar->FileHandle = _lcreat(LogVar->FullName,0);                  ts.Append = HIWORD(Option);
348    }  
349    else                  if (ts.Append & 0x1000) {
350      LogVar->FileHandle = _lcreat(LogVar->FullName,0);                          ts.LogTypePlainText = 1;
351    LogVar->FileOpen = (LogVar->FileHandle>0);                  } else {
352    if (! LogVar->FileOpen)                          ts.LogTypePlainText = 0;
353    {                  }
354      FileTransEnd(OpLog);  
355      return;                  if (ts.Append & 0x2000) {
356    }                          ts.LogTimestamp = 1;
357    LogVar->ByteCount = 0;                  }
358                    else {
359                            ts.LogTimestamp = 0;
360                    }
361    
362                    ts.Append &= 0x1; // 1bitにマスクする
363    
364            }
365            else {
366                    // &h をホスト名に置換 (2007.5.14)
367                    ConvertLogname(LogVar->FullName);
368                    (*SetFileVar)(LogVar);
369            }
370    
371            if (ts.TransBin > 0)
372            {
373                    BinLog = TRUE;
374                    FileLog = FALSE;
375                    if (! CreateBinBuf())
376                    {
377                            FileTransEnd(OpLog);
378                            return;
379                    }
380            }
381            else {
382                    BinLog = FALSE;
383                    FileLog = TRUE;
384                    if (! CreateLogBuf())
385                    {
386                            FileTransEnd(OpLog);
387                            return;
388                    }
389            }
390            cv.LStart = cv.LogPtr;
391            cv.LCount = 0;
392    
393            HelpId = HlpFileLog;
394            /* 2007.05.24 Gentaro */
395            eLineEnd = Line_LineHead;
396    
397            if (ts.Append > 0)
398            {
399                    LogVar->FileHandle = _lopen(LogVar->FullName,OF_WRITE);
400                    if (LogVar->FileHandle>0){
401                            _llseek(LogVar->FileHandle,0,2);
402                            /* 2007.05.24 Gentaro
403                                    If log file already exists,
404                                    a newline is inserted before the first timestamp.
405                            */
406                            eLineEnd = Line_FileHead;
407                    }
408                    else
409                            LogVar->FileHandle = _lcreat(LogVar->FullName,0);
410            }
411            else
412                    LogVar->FileHandle = _lcreat(LogVar->FullName,0);
413            LogVar->FileOpen = (LogVar->FileHandle>0);
414            if (! LogVar->FileOpen)
415            {
416                    FileTransEnd(OpLog);
417                    return;
418            }
419            LogVar->ByteCount = 0;
420    
421    if (! OpenFTDlg(LogVar))          if (! OpenFTDlg(LogVar))
422      FileTransEnd(OpLog);                  FileTransEnd(OpLog);
423  }  }
424  }  }
425    
# Line 326  void LogPut1(BYTE b) Line 452  void LogPut1(BYTE b)
452      }      }
453      else cv.DCount++;      else cv.DCount++;
454    }    }
455    else    else {
456      cv.DCount = 0;      cv.DCount = 0;
457            // ログ採取中にマクロがストールする問題への修正。
458            // ログ採取中に一度マクロを止めると、バッファのインデックスが同期取れなくなり、
459            // 再度マクロを流しても正しいデータが送れないのが原因。
460            // マクロを停止させた状態でもインデックスの同期を取るようにした。
461            // (2006.12.26 yutaka)
462        cv.DStart = cv.LogPtr;
463      }
464  }  }
465    
466  void Log1Byte(BYTE b)  void Log1Byte(BYTE b)
# Line 378  void CommentLogToFile(char *buf, int siz Line 511  void CommentLogToFile(char *buf, int siz
511          DWORD wrote;          DWORD wrote;
512    
513          if (LogVar == NULL || !LogVar->FileOpen) {          if (LogVar == NULL || !LogVar->FileOpen) {
514    #ifdef I18N
515                    char uimsg[MAX_UIMSG];
516                    strcpy(uimsg, "ERROR");
517                    get_lang_msg("MSG_ERROR", uimsg, ts.UILanguageFile);
518                    strcpy(ts.UIMsg, "It is not opened by the log file yet.");
519                    get_lang_msg("MSG_COMMENT_LOG_OPEN_ERROR", ts.UIMsg, ts.UILanguageFile);
520                    ::MessageBox(NULL, ts.UIMsg, uimsg, MB_OK|MB_ICONEXCLAMATION);
521    #else
522                  ::MessageBox(NULL, "It is not opened by the log file yet.", "ERROR", MB_OK|MB_ICONEXCLAMATION);                  ::MessageBox(NULL, "It is not opened by the log file yet.", "ERROR", MB_OK|MB_ICONEXCLAMATION);
523    #endif
524                  return;                  return;
525          }          }
526    
527          logfile_lock();          logfile_lock();
528          WriteFile((HANDLE)LogVar->FileHandle, buf, size, &wrote, NULL);          WriteFile((HANDLE)LogVar->FileHandle, buf, size, &wrote, NULL);
529          WriteFile((HANDLE)LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // 改行          WriteFile((HANDLE)LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // 改行
530            /* Set Line End Flag
531                    2007.05.24 Gentaro
532            */
533            eLineEnd = Line_LineHead;
534          logfile_unlock();          logfile_unlock();
535  }  }
536    
# Line 420  void LogToFile() Line 566  void LogToFile()
566          {          {
567                  if (((cv.FilePause & OpLog)==0) && (! cv.ProtoFlag))                  if (((cv.FilePause & OpLog)==0) && (! cv.ProtoFlag))
568                  {                  {
569                            // 時刻を書き出す(2006.7.23 maya)
570                            // 日付フォーマットを日本ではなく世界標準に変更した (2006.7.23 yutaka)
571                            /* 2007.05.24 Gentaro */
572                            if ( ts.LogTimestamp && eLineEnd ) {
573    #if 0
574                                    SYSTEMTIME      LocalTime;
575                                    GetLocalTime(&LocalTime);
576                                    char strtime[27];
577    
578                                    // format time
579                                    sprintf(strtime, "[%04d/%02d/%02d %02d:%02d:%02d.%03d] ",
580                                                    LocalTime.wYear, LocalTime.wMonth,LocalTime.wDay,
581                                                    LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond,
582                                                    LocalTime.wMilliseconds);
583    #else
584                                            time_t tick = time(NULL);
585                                            char *strtime = ctime(&tick);
586    #endif
587                                    /* 2007.05.24 Gentaro */
588                                    if( eLineEnd == Line_FileHead ){
589                                            _lwrite(LogVar->FileHandle,"\r\n",2);
590                                    }
591                                    _lwrite(LogVar->FileHandle,"[",1);
592                                    // 変換した文字列の終端に \n が含まれているので取り除く。
593                                    _lwrite(LogVar->FileHandle, strtime, strlen(strtime) - 1);
594                                    _lwrite(LogVar->FileHandle,"] ",2);
595                            }
596                            
597                            /* 2007.05.24 Gentaro */
598                            if( b == 0x0a ){
599                                    eLineEnd = Line_LineHead; /* set endmark*/
600                            }
601                            else {
602                                    eLineEnd = Line_Other; /* clear endmark*/
603                            }
604    
605                          _lwrite(LogVar->FileHandle,(PCHAR)&b,1);                          _lwrite(LogVar->FileHandle,(PCHAR)&b,1);
606                          (LogVar->ByteCount)++;                          (LogVar->ByteCount)++;
607                  }                  }
# Line 520  void FileSendStart() Line 702  void FileSendStart()
702    if (strlen(&(SendVar->FullName[SendVar->DirLen]))==0)    if (strlen(&(SendVar->FullName[SendVar->DirLen]))==0)
703    {    {
704      Option = MAKELONG(ts.TransBin,0);      Option = MAKELONG(ts.TransBin,0);
705            SendVar->FullName[0] = 0;
706      if (! (*GetTransFname)(SendVar, ts.FileDir, GTF_SEND, &Option))      if (! (*GetTransFname)(SendVar, ts.FileDir, GTF_SEND, &Option))
707      {          {
708        FileTransEnd(OpSendFile);        FileTransEnd(OpSendFile);
709        return;        return;
710      }      }
# Line 694  BOOL OpenProtoDlg(PFileVar fv, int IdPro Line 877  BOOL OpenProtoDlg(PFileVar fv, int IdPro
877  {  {
878    int vsize;    int vsize;
879    PProtoDlg pd;    PProtoDlg pd;
880    #ifdef I18N
881      HWND Hpd;
882    #endif
883    
884    ProtoId = IdProto;    ProtoId = IdProto;
885    
# Line 745  BOOL OpenProtoDlg(PFileVar fv, int IdPro Line 931  BOOL OpenProtoDlg(PFileVar fv, int IdPro
931      ProtoVar = NULL;      ProtoVar = NULL;
932      return FALSE;      return FALSE;
933    }    }
934    #ifdef I18N
935      pd->Create(fv,&ts);
936    #else
937    pd->Create(fv);    pd->Create(fv);
938    #endif
939    
940    #ifdef I18N
941      Hpd=pd->GetSafeHwnd();
942    
943      GetDlgItemText(Hpd, IDC_PROT_FILENAME, ts.UIMsg, sizeof(ts.UIMsg));
944      get_lang_msg("DLG_PROT_FIELNAME", ts.UIMsg, ts.UILanguageFile);
945      SetDlgItemText(Hpd, IDC_PROT_FILENAME, ts.UIMsg);
946      GetDlgItemText(Hpd, IDC_PROT_PROT, ts.UIMsg, sizeof(ts.UIMsg));
947      get_lang_msg("DLG_PROT_PROTO", ts.UIMsg, ts.UILanguageFile);
948      SetDlgItemText(Hpd, IDC_PROT_PROT, ts.UIMsg);
949      GetDlgItemText(Hpd, IDC_PROT_PACKET, ts.UIMsg, sizeof(ts.UIMsg));
950      get_lang_msg("DLG_PROT_PACKET", ts.UIMsg, ts.UILanguageFile);
951      SetDlgItemText(Hpd, IDC_PROT_PACKET, ts.UIMsg);
952      GetDlgItemText(Hpd, IDC_PROT_TRANS, ts.UIMsg, sizeof(ts.UIMsg));
953      get_lang_msg("DLG_PROT_TRANS", ts.UIMsg, ts.UILanguageFile);
954      SetDlgItemText(Hpd, IDC_PROT_TRANS, ts.UIMsg);
955      GetDlgItemText(Hpd, IDCANCEL, ts.UIMsg, sizeof(ts.UIMsg));
956      get_lang_msg("BTN_CANCEL", ts.UIMsg, ts.UILanguageFile);
957      SetDlgItemText(Hpd, IDCANCEL, ts.UIMsg);
958    #endif
959        
960    (*ProtoInit)(ProtoId,FileVar,ProtoVar,&cv,&ts);    (*ProtoInit)(ProtoId,FileVar,ProtoVar,&cv,&ts);
961    
# Line 874  void KermitStart(int mode) Line 1084  void KermitStart(int mode)
1084        }        }
1085        else        else
1086          (*SetFileVar)(FileVar);          (*SetFileVar)(FileVar);
1087        break;            break;
1088      case IdKmtReceive:      case IdKmtReceive:
1089        FileVar->OpId = OpKmtRcv;        FileVar->OpId = OpKmtRcv;
1090        break;        break;
# Line 891  void KermitStart(int mode) Line 1101  void KermitStart(int mode)
1101        }        }
1102        else        else
1103          (*SetFileVar)(FileVar);          (*SetFileVar)(FileVar);
1104        break;            break;
1105      case IdKmtFinish:      case IdKmtFinish:
1106        FileVar->OpId = OpKmtFin;        FileVar->OpId = OpKmtFin;
1107        break;        break;
# Line 1006  void BPStart(int mode) Line 1216  void BPStart(int mode)
1216      FileVar->OpId = OpBPSend;      FileVar->OpId = OpBPSend;
1217      if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)      if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1218      {      {
1219              FileVar->FullName[0] = 0;
1220        if (! (*GetTransFname)(FileVar, ts.FileDir, GTF_BP, &Option))        if (! (*GetTransFname)(FileVar, ts.FileDir, GTF_BP, &Option))
1221        {            {
1222          ProtoEnd();          ProtoEnd();
1223          return;          return;
1224        }        }
1225      }      }
1226      else      else
1227        (*SetFileVar)(FileVar);        (*SetFileVar)(FileVar);
   
1228    }    }
1229    else /* IdBPReceive or IdBPAuto */    else /* IdBPReceive or IdBPAuto */
1230      FileVar->OpId = OpBPRcv;      FileVar->OpId = OpBPRcv;
# Line 1063  void QVStart(int mode) Line 1273  void QVStart(int mode)
1273      ProtoEnd();      ProtoEnd();
1274  }  }
1275  }  }
1276    
1277    /*
1278     * $Log$
1279     * Revision 1.12  2007/05/25 09:56:05  yutakapon
1280     * タイムスタンプ付きログで1KBごとに不要な改行が入るバグを修正。
1281     *
1282     * Revision 1.11  2007/05/14 14:07:14  maya
1283     * バッファをクリアしていないので落ちる問題を修正した。
1284     *
1285     * Revision 1.10  2007/05/14 13:29:58  maya
1286     * ログファイル名中の &h を、接続中のホスト名に変換する機能を追加した。
1287     *
1288     * Revision 1.9  2007/01/21 16:18:35  maya
1289     * 表示メッセージの読み込み対応
1290     *
1291     * Revision 1.8  2007/01/04 15:11:44  maya
1292     * 表示メッセージの読み込み対応
1293     *
1294     * Revision 1.7  2006/12/25 16:13:54  yutakapon
1295     * ログ採取中にマクロがストールする問題への修正。
1296     * ログ採取中に一度マクロを止めると、バッファのインデックスが同期取れなくなり、
1297     * 再度マクロを流しても正しいデータが送れないのが原因。
1298     * マクロを停止させた状態でもインデックスの同期を取るようにした。
1299     *
1300     * Revision 1.6  2006/08/28 12:27:16  maya
1301     * デフォルトのログファイル名を指定できるようにした。
1302     *   エディットコントロールを "Additional settings" ダイアログに追加した。
1303     *   teraterm.ini ファイルに LogDefaultName エントリを追加した。
1304     *   ファイル名に strftime のフォーマットを使えるようにした。
1305     *
1306     * Revision 1.5  2006/07/23 14:12:26  yutakakn
1307     * ログに含める日付フォーマットを世界標準書式に変更した。
1308     *
1309     * Revision 1.4  2006/07/22 16:15:54  maya
1310     * ログ記録時に時刻も書き込む機能を追加した。
1311     *
1312     * Revision 1.3  2005/05/07 09:49:24  yutakakn
1313     * teraterm.iniに LogTypePlainText を追加した。
1314     *
1315     * Revision 1.2  2005/02/20 14:51:29  yutakakn
1316     * ログファイルの種別に"plain text"を追加。このオプションが有効の場合は、ログファイルに
1317     * ASCII非表示文字の採取をしない。
1318     *
1319     * 現在、無視するキャラクタは以下のとおり。
1320     *  ・BS
1321     *  ・ASCII(0x00-0x1f)のうち非表示なもの
1322     *
1323     * ただし、例外として以下のものはログ採取対象。
1324     *  ・HT
1325     *  ・CR
1326     *  ・LF
1327     *
1328     */

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.12

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