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.5 by yutakakn, Sun Jul 23 14:12:26 2006 UTC revision 1.17 by maya, Mon Aug 13 22:26:08 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      HWND HFTDlg;
181      char uimsg[MAX_UIMSG];
182    
183    FTDlg = new CFileTransDlg();    FTDlg = new CFileTransDlg();
184        
185    if (FTDlg!=NULL)    if (FTDlg!=NULL)
186    {    {
187      FTDlg->Create(fv, &cv);      FTDlg->Create(fv, &cv, &ts);
188      FTDlg->RefreshNum();      FTDlg->RefreshNum();
189      if (fv->OpId == OpLog)      if (fv->OpId == OpLog)
190        FTDlg->ShowWindow(SW_MINIMIZE);        FTDlg->ShowWindow(SW_MINIMIZE);
# Line 181  BOOL OpenFTDlg(PFileVar fv) Line 195  BOOL OpenFTDlg(PFileVar fv)
195    else    else
196      SendDlg = FTDlg; /* File send */      SendDlg = FTDlg; /* File send */
197    
198      HFTDlg=FTDlg->GetSafeHwnd();
199    
200      GetDlgItemText(HFTDlg, IDC_TRANS_FILENAME, uimsg, sizeof(uimsg));
201      get_lang_msg("DLG_FILETRANS_FILENAME", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
202      SetDlgItemText(HFTDlg, IDC_TRANS_FILENAME, ts.UIMsg);
203      GetDlgItemText(HFTDlg, IDC_FULLPATH_LABEL, uimsg, sizeof(uimsg));
204      get_lang_msg("DLG_FILETRANS_FULLPATH", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
205      SetDlgItemText(HFTDlg, IDC_FULLPATH_LABEL, ts.UIMsg);
206      GetDlgItemText(HFTDlg, IDC_TRANS_TRANS, uimsg, sizeof(uimsg));
207      get_lang_msg("DLG_FILETRANS_TRNAS", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
208      SetDlgItemText(HFTDlg, IDC_TRANS_TRANS, ts.UIMsg);
209      GetDlgItemText(HFTDlg, IDCANCEL, uimsg, sizeof(uimsg));
210      get_lang_msg("BTN_CANCEL", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
211      SetDlgItemText(HFTDlg, IDCANCEL, ts.UIMsg);
212      GetDlgItemText(HFTDlg, IDC_TRANSPAUSESTART, uimsg, sizeof(uimsg));
213      get_lang_msg("DLG_FILETRANS_PAUSE", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
214      SetDlgItemText(HFTDlg, IDC_TRANSPAUSESTART, ts.UIMsg);
215      GetDlgItemText(HFTDlg, IDC_TRANSHELP, uimsg, sizeof(uimsg));
216      get_lang_msg("BTN_HELP", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
217      SetDlgItemText(HFTDlg, IDC_TRANSHELP, ts.UIMsg);
218    
219    return (FTDlg!=NULL);    return (FTDlg!=NULL);
220  }  }
221    
# Line 192  BOOL NewFileVar(PFileVar *fv) Line 227  BOOL NewFileVar(PFileVar *fv)
227      if ((*fv)!=NULL)      if ((*fv)!=NULL)
228      {      {
229        memset(*fv, 0, sizeof(TFileVar));        memset(*fv, 0, sizeof(TFileVar));
230        strcpy((*fv)->FullName,ts.FileDir);        strncpy_s((*fv)->FullName, sizeof((*fv)->FullName),ts.FileDir, _TRUNCATE);
231        AppendSlash((*fv)->FullName);        AppendSlash((*fv)->FullName,sizeof((*fv)->FullName));
232        (*fv)->DirLen = strlen((*fv)->FullName);        (*fv)->DirLen = strlen((*fv)->FullName);
233        (*fv)->FileOpen = FALSE;        (*fv)->FileOpen = FALSE;
234        (*fv)->OverWrite = ((ts.FTFlag & FT_RENAME) == 0);        (*fv)->OverWrite = ((ts.FTFlag & FT_RENAME) == 0);
# Line 221  void FreeFileVar(PFileVar *fv) Line 256  void FreeFileVar(PFileVar *fv)
256    }    }
257  }  }
258    
259    // &h をホスト名に置換 (2007.5.14)
260    void ConvertLogname(char *c, int destlen)
261    {
262      char buf[MAXPATHLEN], buf2[MAXPATHLEN], *p = c;
263    
264      memset(buf, 0, sizeof(buf));
265    
266      while(*p != '\0') {
267        if (*p == '&' && *(p+1) != '\0') {
268          switch (*(p+1)) {
269            case 'h':
270              if (cv.Open) {
271                if (cv.PortType == IdTCPIP) {
272                  strncat_s(buf,sizeof(buf),ts.HostName,_TRUNCATE);
273                }
274                else if (cv.PortType == IdSerial) {
275                  strncpy_s(buf2,sizeof(buf2),buf,_TRUNCATE);
276                  _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%sCOM%d", buf2, ts.ComPort);
277                }
278              }
279              break;
280            default:
281              strncpy_s(buf2,sizeof(buf2),p,2);
282              strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
283          }
284          p++;
285        }
286        else {
287              strncpy_s(buf2,sizeof(buf2),p,1);
288              strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
289        }
290        p++;
291      }
292      strncpy_s(c, destlen, buf, _TRUNCATE);
293    }
294    
295  extern "C" {  extern "C" {
296  void LogStart()  void LogStart()
297  {  {
298          LONG Option;          LONG Option;
299            char *logdir;
300    
301          if ((FileLog) || (BinLog)) return;          if ((FileLog) || (BinLog)) return;
302    
# Line 236  void LogStart() Line 308  void LogStart()
308          }          }
309          LogVar->OpId = OpLog;          LogVar->OpId = OpLog;
310    
311            if (strlen(ts.LogDefaultPath) > 0) {
312                    logdir = ts.LogDefaultPath;
313            }
314            else if (strlen(ts.FileDir) > 0) {
315                    logdir = ts.FileDir;
316            }
317            else {
318                    logdir = ts.HomeDir;
319            }
320    
321          if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0)          if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0)
322          {          {
323                  // LOWORD                  // LOWORD
# Line 248  void LogStart() Line 330  void LogStart()
330                  Option = MAKELONG(ts.TransBin,ts.Append |                  Option = MAKELONG(ts.TransBin,ts.Append |
331                                                    (0x1000 * ts.LogTypePlainText) |                                                    (0x1000 * ts.LogTypePlainText) |
332                                                    (0x2000 * ts.LogTimestamp));                                                    (0x2000 * ts.LogTimestamp));
333                  if (! (*GetTransFname)(LogVar, ts.FileDir, GTF_LOG, &Option))  
334                    // ログのデフォルトファイル名を設定 (2006.8.28 maya)
335                    strncat_s(LogVar->FullName, sizeof(LogVar->FullName), ts.LogDefaultName, _TRUNCATE);
336    
337                    ParseStrftimeFileName(LogVar->FullName, sizeof(LogVar->FullName));
338    
339                    // &h をホスト名に置換 (2007.5.14)
340                    ConvertLogname(LogVar->FullName, sizeof(LogVar->FullName));
341    
342                    if (! (*GetTransFname)(LogVar, logdir, GTF_LOG, &Option))
343                  {                  {
344                          FreeFileVar(&LogVar);                          FreeFileVar(&LogVar);
345                          FreeTTFILE();                          FreeTTFILE();
# Line 273  void LogStart() Line 364  void LogStart()
364                  ts.Append &= 0x1; // 1bitにマスクする                  ts.Append &= 0x1; // 1bitにマスクする
365    
366          }          }
367          else          else {
368                    // LogVar->DirLen = 0 だとここに来る
369                    // フルパス・相対パスともに LogVar->FullName に入れておく必要がある
370                    char FileName[MAX_PATH];
371    
372                    // フルパス化
373                    strncpy_s(FileName, sizeof(FileName), LogVar->FullName, _TRUNCATE);
374                    ConvFName(logdir,FileName,sizeof(FileName),"",LogVar->FullName,sizeof(LogVar->FullName));
375    
376                    ParseStrftimeFileName(LogVar->FullName, sizeof(LogVar->FullName));
377    
378                    // &h をホスト名に置換 (2007.5.14)
379                    ConvertLogname(LogVar->FullName, sizeof(LogVar->FullName));
380                  (*SetFileVar)(LogVar);                  (*SetFileVar)(LogVar);
381            }
382    
383          if (ts.TransBin > 0)          if (ts.TransBin > 0)
384          {          {
# Line 299  void LogStart() Line 403  void LogStart()
403          cv.LCount = 0;          cv.LCount = 0;
404    
405          HelpId = HlpFileLog;          HelpId = HlpFileLog;
406            /* 2007.05.24 Gentaro */
407            eLineEnd = Line_LineHead;
408    
409          if (ts.Append > 0)          if (ts.Append > 0)
410          {          {
411                  LogVar->FileHandle = _lopen(LogVar->FullName,OF_WRITE);                  LogVar->FileHandle = _lopen(LogVar->FullName,OF_WRITE);
412                  if (LogVar->FileHandle>0)                  if (LogVar->FileHandle>0){
413                          _llseek(LogVar->FileHandle,0,2);                          _llseek(LogVar->FileHandle,0,2);
414                            /* 2007.05.24 Gentaro
415                                    If log file already exists,
416                                    a newline is inserted before the first timestamp.
417                            */
418                            eLineEnd = Line_FileHead;
419                    }
420                  else                  else
421                          LogVar->FileHandle = _lcreat(LogVar->FullName,0);                          LogVar->FileHandle = _lcreat(LogVar->FullName,0);
422          }          }
# Line 351  void LogPut1(BYTE b) Line 464  void LogPut1(BYTE b)
464      }      }
465      else cv.DCount++;      else cv.DCount++;
466    }    }
467    else    else {
468      cv.DCount = 0;      cv.DCount = 0;
469            // ログ採取中にマクロがストールする問題への修正。
470            // ログ採取中に一度マクロを止めると、バッファのインデックスが同期取れなくなり、
471            // 再度マクロを流しても正しいデータが送れないのが原因。
472            // マクロを停止させた状態でもインデックスの同期を取るようにした。
473            // (2006.12.26 yutaka)
474        cv.DStart = cv.LogPtr;
475      }
476  }  }
477    
478  void Log1Byte(BYTE b)  void Log1Byte(BYTE b)
# Line 403  void CommentLogToFile(char *buf, int siz Line 523  void CommentLogToFile(char *buf, int siz
523          DWORD wrote;          DWORD wrote;
524    
525          if (LogVar == NULL || !LogVar->FileOpen) {          if (LogVar == NULL || !LogVar->FileOpen) {
526                  ::MessageBox(NULL, "It is not opened by the log file yet.", "ERROR", MB_OK|MB_ICONEXCLAMATION);                  char uimsg[MAX_UIMSG];
527                    get_lang_msg("MSG_ERROR", uimsg, sizeof(uimsg), "ERROR", ts.UILanguageFile);
528                    get_lang_msg("MSG_COMMENT_LOG_OPEN_ERROR", ts.UIMsg, sizeof(ts.UIMsg),
529                                             "It is not opened by the log file yet.", ts.UILanguageFile);
530                    ::MessageBox(NULL, ts.UIMsg, uimsg, MB_OK|MB_ICONEXCLAMATION);
531                  return;                  return;
532          }          }
533    
534          logfile_lock();          logfile_lock();
535          WriteFile((HANDLE)LogVar->FileHandle, buf, size, &wrote, NULL);          WriteFile((HANDLE)LogVar->FileHandle, buf, size, &wrote, NULL);
536          WriteFile((HANDLE)LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // 改行          WriteFile((HANDLE)LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // 改行
537            /* Set Line End Flag
538                    2007.05.24 Gentaro
539            */
540            eLineEnd = Line_LineHead;
541          logfile_unlock();          logfile_unlock();
542  }  }
543    
# Line 447  void LogToFile() Line 575  void LogToFile()
575                  {                  {
576                          // 時刻を書き出す(2006.7.23 maya)                          // 時刻を書き出す(2006.7.23 maya)
577                          // 日付フォーマットを日本ではなく世界標準に変更した (2006.7.23 yutaka)                          // 日付フォーマットを日本ではなく世界標準に変更した (2006.7.23 yutaka)
578                          if (ts.LogTimestamp &&                          /* 2007.05.24 Gentaro */
579                                  (Start == 1 || Buf[Start-2] == 0x0a)) {                          if ( ts.LogTimestamp && eLineEnd ) {
580  #if 0  #if 0
581                                  SYSTEMTIME      LocalTime;                                  SYSTEMTIME      LocalTime;
582                                  GetLocalTime(&LocalTime);                                  GetLocalTime(&LocalTime);
# Line 463  void LogToFile() Line 591  void LogToFile()
591                                          time_t tick = time(NULL);                                          time_t tick = time(NULL);
592                                          char *strtime = ctime(&tick);                                          char *strtime = ctime(&tick);
593  #endif  #endif
594                                    /* 2007.05.24 Gentaro */
595                                  // write to file                                  if( eLineEnd == Line_FileHead ){
596                                  if (Start == 1 && ts.Append) {                                          _lwrite(LogVar->FileHandle,"\r\n",2);
                                         _lwrite(LogVar->FileHandle,"\r\n",strlen("\r\n"));  
597                                  }                                  }
598                                  _lwrite(LogVar->FileHandle,"[",1);                                  _lwrite(LogVar->FileHandle,"[",1);
599                                  // 変換した文字列の終端に \n が含まれているので取り除く。                                  // 変換した文字列の終端に \n が含まれているので取り除く。
600                                  _lwrite(LogVar->FileHandle, strtime, strlen(strtime) - 1);                                  _lwrite(LogVar->FileHandle, strtime, strlen(strtime) - 1);
601                                  _lwrite(LogVar->FileHandle,"] ",2);                                  _lwrite(LogVar->FileHandle,"] ",2);
602                          }                          }
603                            
604                            /* 2007.05.24 Gentaro */
605                            if( b == 0x0a ){
606                                    eLineEnd = Line_LineHead; /* set endmark*/
607                            }
608                            else {
609                                    eLineEnd = Line_Other; /* clear endmark*/
610                            }
611    
612                          _lwrite(LogVar->FileHandle,(PCHAR)&b,1);                          _lwrite(LogVar->FileHandle,(PCHAR)&b,1);
613                          (LogVar->ByteCount)++;                          (LogVar->ByteCount)++;
# Line 574  void FileSendStart() Line 709  void FileSendStart()
709    if (strlen(&(SendVar->FullName[SendVar->DirLen]))==0)    if (strlen(&(SendVar->FullName[SendVar->DirLen]))==0)
710    {    {
711      Option = MAKELONG(ts.TransBin,0);      Option = MAKELONG(ts.TransBin,0);
712            SendVar->FullName[0] = 0;
713      if (! (*GetTransFname)(SendVar, ts.FileDir, GTF_SEND, &Option))      if (! (*GetTransFname)(SendVar, ts.FileDir, GTF_SEND, &Option))
714      {          {
715        FileTransEnd(OpSendFile);        FileTransEnd(OpSendFile);
716        return;        return;
717      }      }
# Line 748  BOOL OpenProtoDlg(PFileVar fv, int IdPro Line 884  BOOL OpenProtoDlg(PFileVar fv, int IdPro
884  {  {
885    int vsize;    int vsize;
886    PProtoDlg pd;    PProtoDlg pd;
887      HWND Hpd;
888      char uimsg[MAX_UIMSG];
889    
890    ProtoId = IdProto;    ProtoId = IdProto;
891    
# Line 799  BOOL OpenProtoDlg(PFileVar fv, int IdPro Line 937  BOOL OpenProtoDlg(PFileVar fv, int IdPro
937      ProtoVar = NULL;      ProtoVar = NULL;
938      return FALSE;      return FALSE;
939    }    }
940    pd->Create(fv);    pd->Create(fv,&ts);
941      
942      Hpd=pd->GetSafeHwnd();
943    
944      GetDlgItemText(Hpd, IDC_PROT_FILENAME, uimsg, sizeof(uimsg));
945      get_lang_msg("DLG_PROT_FIELNAME", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
946      SetDlgItemText(Hpd, IDC_PROT_FILENAME, ts.UIMsg);
947      GetDlgItemText(Hpd, IDC_PROT_PROT, uimsg, sizeof(uimsg));
948      get_lang_msg("DLG_PROT_PROTO", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
949      SetDlgItemText(Hpd, IDC_PROT_PROT, ts.UIMsg);
950      GetDlgItemText(Hpd, IDC_PROT_PACKET, uimsg, sizeof(uimsg));
951      get_lang_msg("DLG_PROT_PACKET", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
952      SetDlgItemText(Hpd, IDC_PROT_PACKET, ts.UIMsg);
953      GetDlgItemText(Hpd, IDC_PROT_TRANS, uimsg, sizeof(uimsg));
954      get_lang_msg("DLG_PROT_TRANS", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
955      SetDlgItemText(Hpd, IDC_PROT_TRANS, ts.UIMsg);
956      GetDlgItemText(Hpd, IDCANCEL, uimsg, sizeof(uimsg));
957      get_lang_msg("BTN_CANCEL", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
958      SetDlgItemText(Hpd, IDCANCEL, ts.UIMsg);
959    
960    (*ProtoInit)(ProtoId,FileVar,ProtoVar,&cv,&ts);    (*ProtoInit)(ProtoId,FileVar,ProtoVar,&cv,&ts);
961    
962    PtDlg = pd;    PtDlg = pd;
# Line 928  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 945  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 1060  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 1120  void QVStart(int mode) Line 1276  void QVStart(int mode)
1276    
1277  /*  /*
1278   * $Log$   * $Log$
1279     * Revision 1.17  2007/08/13 22:26:08  maya
1280     * 国際化関数を修正した。
1281     * NO_I18N マクロを削除した。
1282     *
1283     * Revision 1.16  2007/08/08 15:56:35  maya
1284     * 安全な関数を使用するように変更した。
1285     *
1286     * Revision 1.15  2007/06/06 14:02:53  maya
1287     * プリプロセッサにより構造体が変わってしまうので、INET6 と I18N の #define を逆転させた。
1288     *
1289     * Revision 1.14  2007/05/31 14:39:05  maya
1290     * 接続時に自動的にログ採取を開始できるようにした。
1291     *
1292     * Revision 1.13  2007/05/30 16:04:27  maya
1293     * 標準のログ保存先を指定できるようにした。
1294     *
1295     * Revision 1.12  2007/05/25 09:56:05  yutakapon
1296     * タイムスタンプ付きログで1KBごとに不要な改行が入るバグを修正。
1297     *
1298     * Revision 1.11  2007/05/14 14:07:14  maya
1299     * バッファをクリアしていないので落ちる問題を修正した。
1300     *
1301     * Revision 1.10  2007/05/14 13:29:58  maya
1302     * ログファイル名中の &h を、接続中のホスト名に変換する機能を追加した。
1303     *
1304     * Revision 1.9  2007/01/21 16:18:35  maya
1305     * 表示メッセージの読み込み対応
1306     *
1307     * Revision 1.8  2007/01/04 15:11:44  maya
1308     * 表示メッセージの読み込み対応
1309     *
1310     * Revision 1.7  2006/12/25 16:13:54  yutakapon
1311     * ログ採取中にマクロがストールする問題への修正。
1312     * ログ採取中に一度マクロを止めると、バッファのインデックスが同期取れなくなり、
1313     * 再度マクロを流しても正しいデータが送れないのが原因。
1314     * マクロを停止させた状態でもインデックスの同期を取るようにした。
1315     *
1316     * Revision 1.6  2006/08/28 12:27:16  maya
1317     * デフォルトのログファイル名を指定できるようにした。
1318     *   エディットコントロールを "Additional settings" ダイアログに追加した。
1319     *   teraterm.ini ファイルに LogDefaultName エントリを追加した。
1320     *   ファイル名に strftime のフォーマットを使えるようにした。
1321     *
1322   * Revision 1.5  2006/07/23 14:12:26  yutakakn   * Revision 1.5  2006/07/23 14:12:26  yutakakn
1323   * ログに含める日付フォーマットを世界標準書式に変更した。   * ログに含める日付フォーマットを世界標準書式に変更した。
1324   *   *

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.17

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