/* DIVIDE_START=..\common.doc */
	AccessRtBbs
		AccessRtBbsBufPtr
		AccessRtBbsAutoMode
			FORUMup		発言をアップする
				CHKcom1
		isEscChar
	cputs consol/consol.c で定義
	RtBbsWithOutQuit
		RtBbsExMoreSw
		RtBbsApply			サインアップ

	定義ファイルの読み書き
		ReadCatlogDef		WriteCatlogDef

	lastSayNum
	SetOptions
		SetRtBbsListMenu
			SetRtBbsListMenuSub
/* DIVIDE_END */

/* DIVIDE_START=..\common.c */
/*
	CheckMainLoop

	isNewFile
	MakeTreeMain
		MakeTreeSort1
			MakeTreeSort2
				MakeTreeSort3
		MakeTreeMainBate

	PrintIndexData						インデックス・データの表示
	CheckAndMakeCatlog2Index
		CheckAndMakeCatlog2IndexSw		インデックスの作り直し
		MakeCatlog2IndexSub2

内部変数の定義
	構造体
		struct CatlogIndex

第１段階
	CheckMain	メイン関数
		インデックスの変更？
			ChangeCatlog1to2Index	変更済スイッチ
			CheckAndMakeCatlog2Index();
			WriteCatlogDef							CATLOG2.DEFを変更
		Windows版での処理
			ReStoreLZHSw	StoreLZHSw		DeleteOldFileSw
		CheckMainCatlogMainSw
		checkMainSub( inDir );
			以下の変数を初期化
				CheckAbortSw AllHatsugenSu CollectFileNumber CollectFileSize
			検索するファイルの初期化
			以下の変数を初期化
				catlog max_catlog Idx MaxIdx
			変数のチェック
				OutDir inDir 
			インデックス・モードのチェック
				check_index_mode();
			検索しない発言のタイプを記録している変数の初期化
				CheckMainSetWithoutSearchMesType();
			TmpDir の下のファイルを全部削除する
				RemoveLzhDir( FileName );
			今日の日付の設定
				SetToday( );
			以下の変数を初期化
				max_catlog HatsugenSu 
				MaxIdx 
			「削除するファイル」の一覧ファイルの削除
				SetTmpDirFile
					DEL_FILE_TABLE_FILE_NAME FORCE_DEL_FILE_TABLE_FILE_NAME
			第１段階の実行
				CheckMainLoop	ログファイルを探す
					CatlogFindFirst
				CheckMainLoop の事後処理
					SaveSayDataFpo 
			第３段階の実行
				CheckMainCatlogMain();
				確保した領域を解放する
					catlog max_catlog 
		disp_start_check_file
	発言データの書き込み
		CatlogFpo
	検索するファイル しないファイル
		isSearchFile isWithoutSearchFile
		UpdateLzhFile UpdateLzhFile_sub collect_system
		DeleteOldFileSw		今日より古いファイルの削除
	整理済ファイルの処理
		isCATLOGFile isCatlogFileSw RenameAttrStr
		Check1FileCatlog DelIndexDataFromIndexFile
	引用発言の処理
		InyouSw isInyouLine isSkipLine FileCopyInyou

第３段階
		CheckMainCatlogMain CheckMainCatlogMain1Kaigi catlog_loop_sub
		get_idx_data
		Sort* SortCatlogDataFunc
		FileCopy FileCopyInyou append_idx_data
		isNewFile catlogP
		RemoveLzhDir
	第３段階を実行するかどうかの内部スイッチ
		CheckMainCatlogMainSw
	TOPMENU に ForumName をはりつける
		CheckAndSetForumNameData


その他の処理
	整理済ファイルから会議室の内容を表す文字列を抽出し、ファイルに書き出す。
											ファイル名: KAIGI_TMP_FILE_NAME
		GetKaigiName
	発言のＩＤ検索
		SearchIdSayMain
		SearchID
		SearchIdSayMainSw		CATLOG 済のファイルから発言データを作る
	ＩＤ←→ハンドル表作成
		SearchIdNameMain	SearchIdNameLoop
		ID_HANDLE_FORMAT
	インデックス整理
		ArrangeIndexData
		ArrangeIndexDataOldestDate	最古の発言日時
		DeleteIndexData				インデックスから fileNum のデータを削除する
	インデックスの変更
		CheckAndMakeCatlog2Index
	汎用関数
		InitialInsideVars
		SetInsideTmpDir
		ヒープ領域の確保
			mallocIdxSub
		ファイル入力の高速化
			initial_check_pool
		ファイルの検索
			CatlogFindFirst CatlogFindFirstLoop

中断判定
CheckAbort CheckAbortSw

その他
	MakeUpDLInto1File_loop
	Catlog3Lib Lib_List checkSetLibNumber
*/

//	#define		MAIN			2
#define		COMMON_MAIN		2

#ifdef		TMENU	
#include	"common.h"
#endif

#define		DO_ON_MEMORY	1		// メモリ上で処理を行う
#undef		DO_ON_MEMORY

#ifdef		DO_ON_MEMORY					// メモリ上で処理を行う
	struct	SayData		*Idx = NULL;
			int		MaxIdx;
			int		IdxP ;
#endif


static		char	catlog_findfirst_path[ 256 ] ;
static		int		save_start , save_end;
static		struct	CATLOG		*catlog= NULL;
static		int		max_catlog = 0;


//	###########################################################################
//	##### CheckAbort ##########################################################
//	###########################################################################
void	CheckAbort()
{
#ifdef	TMENU
	EVENT	*evnt;

	if ( CheckAbortSw == YES )									return;

	MMI_iosense();
	if ( MMI_GetEvnt( EVALL , &evnt ) == NOERR ) {
		// イベントがあった
		switch( evnt->what ) {
			case EVMOSDN:
				if ( ( evnt->shift & SRIGHTBTN ) == SRIGHTBTN ) {
					if ( get_yesno( "\n 中断します" ) == YES ) {
						CheckAbortSw= YES;
					};
//				} else {
//					MMI_ExecEvnt( evnt );
				};
				break;
			case EVKEY:
				if ( evnt->info == ' ' ) {
					if ( get_yesno( "\n 中断します" ) == YES ) {
						CheckAbortSw= YES;
					};
//				} else {
//					MMI_ExecEvnt( evnt );
				};
				break;
			default:
					MMI_ExecEvnt( evnt );
				break;
		};
	};

#else		// VC++ の場合

#endif
}

/******************************************/
/* path を検査してﾃﾞｨﾚｸﾄﾘがない場合は作る */
/******************************************/
void	check_and_make_output_path( const char *path )
{
	char	full[ 128 ],*p;
#ifdef	TMENU
	char	buffer[ 128 ];
#endif
	int		drive;

	strcpy( full , path );

	/* path の最後がファイル名の場合はファイル名を削除する */
	p = last_yen( full ) + 1;
	*p = '\0';

	p = full;
	if ( p[1] == ':' ) {
		p += 2;		/* ドライブ名を読み飛ばす */
		drive = toupper( *full ) - 'A';
	} else {
		drive = 
#ifdef	TMENU
					FM_GetCurrentDisk() - 'A';
#else
					0;
#endif
	};
	if ( *p == '\\' )	p++;		/* ルート・ディレクトリの場合 */
	if ( *p == '\0' )	return;

#ifdef	TMENU
	FM_GetCurrentDir( drive + 'A', buffer );
#endif

	while ( *p ) {
		while ( *p ) {
			if ( *p == '\\' )	break;
			p++;
		};
		/* 最初の \\ */
		*p = '\0';		/* \\ を削除する */
		if ( chdir( full ) < 0 ) {
			/* ディレクトリが存在しない？ */
			if (	mkdir( full ) != 0
//			&&		errno == 0x05
			) {
				sprintf(str,"<%s>でディレクトリ<%s>が作れません",
					path,full
				);
				error_return( str );	return;
			};
		};
		*p++ = '\\';
	};
#ifdef	TMENU
	chdir( buffer );
#endif
}

/*****************************/
/* MesNum を設定しておくこと */
/*****************************/
void	set_index_file_name( char *fileName, char *forumName )
{
	if ( *IndexDir != '\0' ) {		strcpy( fileName , IndexDir );
	} else {						strcpy( fileName , OutDir );
	};
	append_yen( fileName );
	if ( CheckRtBbsLogSw == YES )	strcat( fileName, "RT-BBS\\" );
	if ( IndexModeSw == NO ) {
		strcat( fileName, IDX_FILE_NAME );
		check_and_make_output_path( fileName );
		return;
	};
	switch( MesNum ) {
		case HP:
			strcat( fileName , "HP\\" );
			strcat( fileName , forumName );		strcat( fileName, "\\" );
			break;
		case CLIP:
			strcat( fileName , "CLIP\\" );				break;
		case PATIO:
			strcat( fileName , "PATIO\\" );
			strcat( fileName , forumName );		strcat( fileName, "\\" );
			break;
		case MAIL:
		case ALL_MAIL:
			strcat( fileName , "NIFMAIL\\" );			break;
		case BILL:
			strcat( fileName , "BILL\\" );				break;
		case COLLECT_ID:
			strcat( fileName , "COLLECT\\" );			break;
		default:
			strcat( fileName , forumName );		strcat( fileName, "\\" );
			break;
	};
	strcat( fileName , IDX_FILE_NAME );
	check_and_make_output_path( fileName );
}

static	int		is_idx_data( )
{
	int	i;

	for ( i=0 ; i<save_end ; i++ ) {
		if (	catlog[i].SayNum == catlog[save_end].SayNum
		&&		catlog[i].date   == catlog[save_end].date
		) {
			return( YES );
		};
	};
	return( NO );
}

static	int
DeleteStructCatlogSort( const void *pp1, const void *pp2 )
{
	const	struct	CATLOG	*p1, *p2;

	p1= (const struct CATLOG *)pp1;
	p2= (const struct CATLOG *)pp2;

	/* 次の順序でソートする
		(1) 発言日時
		(2) 発言番号
	*/
	if ( MesNum == LIB ) {
		/* LIB は発言番号 → 発言日時 の 順 */
		if ( p1->SayNum != p2->SayNum )		return( p1->SayNum - p2->SayNum );
		if ( p1->date < p2->date )			return( -1 );
		if ( p1->date > p2->date )			return(  1 );
		return( 0 );
	};

	if ( p1->date == p2->date )				return( p1->SayNum - p2->SayNum );
	if ( p1->date < p2->date )				return( -1 );
	if ( p1->date > p2->date )				return(  1 );
	return( 0 );
}

static	void	DeleteStructCatlog()
{
	int		delStart;

	/* 古い方から３分の１の発言データを破棄 */
	if ( save_start > 0 ) {		delStart= save_start / 3;
	} else {					delStart= save_end   / 3;
	};
#ifdef	TMENU
	mess_check {
		sprintf( YesNoMes,
			"\n内部領域が溢れた(%d個)ので、古い発言データを削除(%d個)します。"
			, save_end, delStart
		);
		PrintMessage( YesNoMes );
	};
#endif
	/* 1994.7.3 追加 発言日時の順にソート */
	/* 発言日時 → 発言番号でソートする */
		qsort((char *)catlog, save_end, sizeof(struct CATLOG)
			, DeleteStructCatlogSort
		);
	/* 発言データを破棄 */
	memmove(	(char *)catlog
				, &catlog[delStart]
				, sizeof(struct CATLOG) * ( save_end - delStart + 1 )
	);
	/* ポインタの調整 */
	if ( save_start > 0 )	save_start -= delStart;
	save_end -= delStart;
}

static	struct	CatlogIndex		catlogIndex;


/*
static	void	PrintIndexData( const struct CatlogIndex index )
{
	char	str1[ 128 ], str2[ 128 ];

	CheckAbort();
	if ( CheckAbortSw == YES )								return;

#ifdef	TMENU
	long_to_date( str2, index.SayDate );
	sprintf( YesNoMes, 
"\n"
"Forum:<%s> MesNum:%3d FileNum:%2d SayNum:%4d ComNum:%4d SayDate:<%s> seek:%8ld"
		, index.ForumName
		, index.MesNum
		, index.FileNum
		, index.SayNum
		, index.ComNum
		, str2
		, index.seek
	);
	WriteCATLOGMessage( YesNoMes );

	Long2Id( str1, index.SayId );
	sprintf( YesNoMes, 
"\n"
"SayId:<%s> Handle:<%s> Mes:<%s>"
		, str1
		, index.Handle
		, index.Mes
	);
	WriteCATLOGMessage( YesNoMes );
#endif
}
*/

static	int		FileNum;

// ForumName と MesNum を設定しておくこと
static	void	get_idx_data( const int checkFileNumSw )
{
	FILE	*fpi;
	char	fileName[ MAX_FILENAME_LEN ];
	long	seek;

	if ( checkFileNumSw == NO )			FileNum = 0;

	set_index_file_name( fileName, ForumName );

	if ( MesNum == ALL_MAIL )	MesNum = MAIL;
	if ( ( fpi = fopen( fileName, "rb" ) ) == NULL )			return;

	// ファイルからデータを読み込む
	seek = 0L;
	while( fread( &catlogIndex, sizeof(struct CatlogIndex), 1, fpi ) == 1 ) {
		catlog[ save_end ].seek_ichi = seek;
		seek= ftell( fpi );								// 次のデータ用

		if ( catlogIndex.MesNum != MesNum )						continue;
		if ( catlogIndex.RtBbsSw != CheckRtBbsLogSw )			continue;
		if ( strcmp( catlogIndex.ForumName, ForumName ) != 0 )	continue;

		// 1995.5.23 追加
		if ( checkFileNumSw == YES ) {
			if ( catlogIndex.FileNum != FileNum )				continue;
		} else {
			// 新しい番号をセットしておく
			if (FileNum<catlogIndex.FileNum)	FileNum = catlogIndex.FileNum;
		};

//		PrintIndexData( catlogIndex );

		catlog[ save_end ].date		= catlogIndex.SayDate;
		catlog[ save_end ].SayNum	= catlogIndex.SayNum;
		catlog[ save_end ].ComNum	= catlogIndex.ComNum;	// コメント番号
		if ( is_idx_data() == NO ) {
			catlog[ save_end ].ahure	= 0x00;
			save_end++;
			if ( save_end + 1 >= max_catlog )	DeleteStructCatlog( );
		};
	};
	fclose( fpi );
}

// error file 名の処理
static	void	error_full_name_sub( const char *typ , const char *id_name )
{
	int		i;
	char	str[ 24 ];

	sprintf( YesNoMes, "\n<%s>の%sのデータが多すぎます\n", id_name , typ );
	for (i=0;i<10;i++) {
		sprintf( str, "<%s.%s%d> ",id_name , typ , i);
		strcat( YesNoMes, str );
	};
	strcat( YesNoMes, "のデータを違うﾃﾞｨﾚｸﾄﾘに移動して下さい｡");
	PrintMessage( YesNoMes );
	error_end();
}

void	error_full_name( )
{
	switch ( MesNum ) {
		case CLIP:	error_full_name_sub( "CLIP", ForumName );			break;
		case PATIO:	error_full_name_sub( "PATIO", ForumName );			break;
		case HP:	error_full_name_sub( "HP"   , ForumName );			break;
		case MAIL:	error_full_name_sub( "MAIL" , ForumName );			break;
		case ALL_MAIL:	error_full_name_sub( "ALL_MAIL" , ForumName );	break;
		case BILL:	error_full_name_sub( "BILL" , BILL_FILE_NAME );		break;
		case COLLECT_ID:
					error_full_name_sub( "COLLECT_ID" , ForumName );	break;
		default:	error_full_name_sub( "MES"  , ForumName );			break;
	};
}

static	void	set_catlog_file_line_1( const char *mes )
{
	strcpy( str , "-------------------------------------------------------- Resort by CATLOG" );
	strncpy( str , mes , strlen( mes ) - 1 );
}

// CatlogFpo をオープンする
//		result : YES	新規ファイル
//		result : NO		追加ファイル
// 呼ぶ前に FileNum を設定しておくこと
static	int		OpenAndCheckNewFile( )
{
	if ( CatlogFpo != NULL ) {	fclose( CatlogFpo );	CatlogFpo= NULL;	};
	set_file_name( FileName, ForumName, MesNum, FileNum );
	if ( (CatlogFpo = fopen( FileName , "ab" ) ) == NULL ) {
		er_open( FileName, 1, "整理済ファイルのオープン" );
	};
	if ( ftell( CatlogFpo ) == 0L )				return( YES );
	return( NO );
}

static	void	Write1stLine( const char *forumNameLine, const char *kaigi )
{
	int		sw;
	char	str1[ 128 ];

	sw = YES;
	switch ( MesNum ) {
		case CLIP:	strcpy( str1 , "CLIP  " );
					strcpy( ForumName , "CLIP" );					break;
		case PATIO:	sprintf( str1 , "PATIO:%s  " , ForumName );
					sw = NO;										break;
		case HP:	sprintf( str1 , "HP:%s  " , ForumName );
					/* 1994.2.13 １行追加 */
					sw = NO;										break;
		case MAIL:
		case ALL_MAIL:
					if ( Mail1Sw == YES ) {
						strcpy( str1 , "ALL-MAIL  " );
					} else {
						sprintf( str1 , "MAIL:%s  " , ForumName );
					};
					break;
		case BILL:	strcpy( str1 , "BILL:BILL  " );
					strcpy( ForumName , "BILL" );					break;
		case COLLECT_ID:
					sprintf( str1, "COLLECT_ID:%s  ",ForumName );	break;
		/* 会議室の発言 */
		default:
					if ( CheckRtBbsLogSw == YES ) {
						sprintf(str1, "RT-BBS:%s MES:%d  ", ForumName, MesNum);
					} else {
						sprintf(str1, "FORUM:%s MES:%d  ",  ForumName, MesNum);
					};
					sw = NO;										break;
	};
	set_catlog_file_line_1( str1 );
	catlog_fprintf( str );						// １行目
	if ( sw == NO ) {
		catlog_fprintf( forumNameLine );		// フォーラム名の行
		if ( MesNum != HP ) {
			catlog_fprintf( kaigi );			// 会議室名の行
		};
	};
}

static	int		getNewFileNum()
{
	int		count, max;
	FILE	*fp;

	if ( CatlogFpo != NULL ) {	fclose( CatlogFpo );	CatlogFpo= NULL;	};
	if ( MesNum < 0 ) {
		if ( MesNum == HP || MesNum == PATIO ) {	max = 10 + 26;
		} else {									max = 10;
		};
	} else {										max = 100;
	};

	for ( count = 0; count < max ; count++ ) {
		set_file_name( FileName, ForumName, MesNum, count );
		if ( ( fp= fopen( FileName, "r" )) == NULL)			return( count );
		fclose( fp );
	};
	PrintMessage( "\n新しいファイルを作ることができません。");
	error_full_name( );
	return( 0 );
}

static	int		isNewFile( int catlogP )
{
	/* ファイルの大きさが大きくなった時 */
	if ( ftell( CatlogFpo ) >= (long)MaxCatlogFileSize*1024L )	return( YES );

	// 会議室によってファイルサイズを決定する
	/* メールを１つのファイルで処理する場合は新しいファイルは作らない */
	/* 将来的には新しいファイルを作っても良いと思われる               */

/* 1994.10.1 メールも新しいファイルを作るようにする
	if (	Mail1Sw == YES
	&&		(	MesNum == MAIL
			||	MesNum == ALL_MAIL
			)
	)															return( NO );
*/
	/* フォーラムの会議室かＨＰの発言ではない時 */
	switch( MesNum ) {
		case HP:
		case PATIO:								break;
		default:
			if ( 1<= MesNum && MesNum <= MAX_KAIGISHITSU )	break;
			return ( NO );
	};

	// 1994.10.1 仕様の変更
	if (	MakeNewFileSmallSw == YES
	&&		catlogP > 0
	) {				// 発言番号が小さい
		if ( catlog[catlogP].SayNum < catlog[catlogP-1].SayNum ) {
																return( YES );
		};
	};
	if (	NewFileSw == YES
	&&		( catlog[catlogP].SayNum % 1000 ) == 1
	)															return( YES );
	return( NO );
}

static	int		isWriteForumNameLine( int catlogP )
{
	/* フォーラムの会議室かＨＰの発言ではない時 */
	switch( MesNum ) {
		case COLLECT_ID:										return( YES );
		case HP:
		case PATIO:								break;
		default:
			if ( 1<= MesNum && MesNum <= MAX_KAIGISHITSU )	break;
			return ( NO );
	};
	if ( catlog[catlogP].SayNum % 1000 == 1 )					return( YES );
	return( NO );
}

/*
		次の順序でソートを行う
			1. 発言の日時でソートする
			2. 発言番号でソートする ただし、MAILはソートしない
*/
static	int	SortCatlogDataFunc( const void *p11 , const void *p21 )
{
	SayLong		sayNum1, sayNum2;

	const struct CATLOG *p1 = (const struct CATLOG *)p11;
	const struct CATLOG *p2 = (const struct CATLOG *)p21;

	// 日付を調べる
	if ( p1->date < p2->date )								return( -1 );
	if ( p1->date > p2->date )								return(  1 );
	// 同じ日付の場合
	sayNum1= p1->SayNum;
	sayNum2= p2->SayNum;
	if ( MesNum == HP ) {
		if ( sayNum1 < sayNum2 ) {
			// 通常は負の数を返さなければならないが………
			if ( sayNum1 < 20 && 980 < sayNum2 )			return(  1 );
		} else if ( sayNum2 < sayNum1 ) {
			// 通常は正の数を返さなければならないが………
			if ( sayNum2 < 20 && 980 < sayNum1 )			return( -1 );
//		} else {											return(  0 );
		};
	};
	return( sayNum1 - sayNum2 );
}

/*
		次の順序でソートを行う
			1. 発言の日時でソートする
			2. 発言番号でソートする ただし、MAILはソートしない
*/
static	void	SortCatlogData()
{
	/* 登録データがない場合や 1 個だけの場合はソートしない */
	if ( save_start == save_end )		return;
	if ( save_start == save_end - 1 )	return;

	qsort( (char *)catlog + save_start * sizeof( struct CATLOG ) ,
		save_end - save_start,
		sizeof( struct CATLOG ) ,
		SortCatlogDataFunc
	);
}

static	int		isInyouLine( const char *psp, const char *nsp )
{
	if ( isMesInputLine( psp, nsp ) == YES )					return( YES );
	if ( isMesForumNameLine( psp ) == YES )						return( YES );
	if ( isMesHyoudaiLine( psp, nsp ) == YES )					return( YES );
	if ( isMailFirstLine( psp, nsp ) == YES )					return( YES );
	if ( isBillFirstLine( psp ) == YES )						return( YES );
	if ( isHpHyoudaiLine( psp ) == YES )						return( YES );
	if ( isLIBFirstLine( psp ) == YES )							return( YES );
	if ( isCLIPFirstLine( psp ) == YES )						return( YES );
	if ( isCLIPLine( psp ) == YES )								return( YES );

	return( NO );
}

// ２行で１セット
static	const	char	*SkipLine[] = {
	"続き（改行で表示　S:次の発言）",
	"＞",

	NULL,	NULL
};

static	int		isSkipLine( const char *psp, const char *nsp )
{
	int		i;

	for ( i=0; SkipLine[i] != NULL ; i++ ) {
		if (	matchstr( psp, SkipLine[i  ] ) == YES
		&&		matchstr( nsp, SkipLine[i+1] ) == YES
		)			return( YES );
	};
	return( NO );
}

static	void
FileCopyInyou(
	const int mesNum,
	const char *fileName,
	long start,
	long end,
	FILE *fpo
) {
	char	strSub[ LINE + 2 ];
	FILE	*fpi;

	if ( ( fpi = fopen( fileName, "r" ) ) == NULL )			return;
	fseek( fpi, start, SEEK_SET );
	fgets( str, LINE, fpi );	fputs( str, fpo );	// １行目はそのまま書き出す
	fgets( str, LINE, fpi );
	while( ftell( fpi ) < end ) {
		if ( fgets( strSub, LINE, fpi ) == NULL )				break;
		if ( isInyouLine( str, strSub ) == YES ) {
			fputc( '>', fpo );
			fputs( str, fpo );
		} else if ( isSkipLine( str, strSub ) == YES ) {
			// str strSub は読み飛ばす
			*str= '\0';
			if ( fgets( strSub, LINE, fpi ) == NULL )			break;
		} else {
			fputs( str, fpo );
		};
		strcpy( str, strSub );
	};
	if ( *str != '\0' ) {
		fputs( str, fpo );
	};
	fclose( fpi );

	/* 最後にデリミタを加える */
	if (	mesNum == PATIO
	||		( 1<= mesNum && mesNum <= MAX_KAIGISHITSU )
	) {
		fwrite( delimitter, 1, 4, fpo );
	};
}

/************************************************************/
/* ここを呼ぶ前にフォーラム名と会議室番号を設定しておくこと */
/************************************************************/
static	void	catlog_loop_sub( const char *file )
{
			int				i, d, newFileSw;
			long			seek;
			FILE			*fpi1 ;
			FILE			*fp ;
			FILE			*IndexFpo;
			char			fileName[ MAX_FILENAME_LEN ];

	/*****************************************************/
	/* CATLOG_IDX から登録済みの発言のデータをメモリーへ */
	/*****************************************************/
	save_start= save_end= 0;
	get_idx_data( NO );			// FileNum はインデックス中の最大値
	save_start= save_end;

	/***********************************************/
	/* file から登録済みの発言のデータをメモリーへ */
	/***********************************************/
	if ( ( fpi1 = fopen( file , "rb" ) ) == NULL ) {
		er_open( file, 0, "catlog_loop_sub" );
	};
	seek= 0L;
	while( fread(&saveSayData,sizeof(struct SaveSayData),1,fpi1 ) == 1 ) {
		catlog[ save_end ].seek_ichi = seek;
		seek= ftell( fpi1 );							// 次のデータ用
		strcpy( SayId, saveSayData.ForumName );			// MAIL で使う
		if ( saveSayData.MesNum == COLLECT_ID ) {
			Long2Id( SayId, saveSayData.SayId );
		};
		catlog[ save_end ].SayNum	= saveSayData.SayNum;	// 発言番号
		catlog[ save_end ].date		= saveSayData.SayDate;
		catlog[ save_end ].ComNum	= saveSayData.ComNum;
		/* 登録済み？ */
		if ( is_idx_data() == NO ) {
			save_end++;
			if ( save_end + 1 >= max_catlog )	DeleteStructCatlog( );
		};
	};
	fclose( fpi1 );
	catlog[save_end].seek_ichi = 0;
	catlog[save_end].SayNum = 0;
	catlog[save_end].date = 0L;
	catlog[save_end].ComNum = 0;

	/**************************/
	/* 全て登録済みならば終了 */
	/**************************/
	if ( save_start >= save_end )		return;
	SortCatlogData();
	HatsugenSu = save_end - save_start;
	i = save_start;

	fp = fopen( file , "rb" );					/* error check は実行済み */

	fseek( fp, catlog[i].seek_ichi, SEEK_SET );
	fread( &saveSayData, sizeof(struct SaveSayData),1,fp );
	CheckRtBbsLogSw		= saveSayData.RtBbsSw;
	strcpy( ForumNameLine, saveSayData.ForumNameLine );
	strcpy( ForumNameLineSub, saveSayData.ForumNameLineSub );

	// 1995.5.13 変更 ↓
	// 発言の本文を書き出すと同時に インデックス・データも書き出す
	if ( MesNum == ALL_MAIL )	MesNum = MAIL;
	set_index_file_name( fileName, ForumName );
	if ( ( IndexFpo = fopen( fileName , "ab+" )) == NULL ) {
		strcpy( FileName, fileName );
		error_open_file( "インデックスの追加" );
		return;
	};
	catlogIndex.MesNum = MesNum;
	strcpy( catlogIndex.ForumName, ForumName );

	// 整理済ファイルのオープン
	newFileSw				= OpenAndCheckNewFile( );
	catlogIndex.FileNum		= FileNum;

	while ( i < save_end ) {
		d = fseek( fp, catlog[i].seek_ichi, SEEK_SET );
		if ( d != 0 ) {
			sprintf(str,"catlog_loop_sub で fseek()ができません。=%d",d);
			error_bug( str );
		};
		/* *****log整理   の行 */
		if ( fread(&saveSayData,sizeof(struct SaveSayData),1,fp ) != 1 ) {
			PrintMessage( "\nプログラムのエラーです（catlog_loop_sub）" );
			sprintf(YesNoMes,"\n" "FileName=%s file =%s",FileName,file);
			PrintMessage( YesNoMes );
			sprintf(YesNoMes,"\n" "i=%d,save_start=%d,save_end=%d",
				i,	save_start,	save_end
			);
			PrintMessage( YesNoMes );
			sprintf(YesNoMes,"\n" "ftell(fp)=%ld ftell(CatlogFpo)=%ld",
				ftell(fp),	ftell(CatlogFpo)
			);
			PrintMessage( YesNoMes );
			sprintf( YesNoMes,"\n" "seek_ich(%ld)が??",catlog[i].seek_ichi);
			PrintMessage( YesNoMes );
			error_end(  );
		};

		if ( newFileSw == NO && isNewFile( i ) == YES ) {
			catlogIndex.FileNum= FileNum=		getNewFileNum();
			newFileSw=							OpenAndCheckNewFile( );
		};

		/* 現在の名前を変えて新しいファイルをopenする */
		if (	newFileSw == YES
		||		isWriteForumNameLine( i ) == YES
		) {
			Write1stLine(
				saveSayData.ForumNameLine, saveSayData.ForumNameLineSub
			);
		};
		newFileSw = NO;

		// まず、インデックス・データを書き出す
		catlogIndex.FileNum	= FileNum;
		catlogIndex.RtBbsSw	= saveSayData.RtBbsSw;
		catlogIndex.SayNum	= saveSayData.SayNum;			// 発言番号
		catlogIndex.ComNum	= saveSayData.ComNum;			// コメント元番号
		catlogIndex.SayDate	= saveSayData.SayDate;			// 発言日時
		catlogIndex.seek		= ftell( CatlogFpo );			// Seek位置
		catlogIndex.SaySize	= saveSayData.BEnd - saveSayData.BStart;
		catlogIndex.SayLine	= saveSayData.GEnd - saveSayData.GStart;
															// 発言の大きさ
		catlogIndex.SayId		= saveSayData.SayId;		// 発言者ID
		strcpy( catlogIndex.Handle, saveSayData.Handle );	// 発言者のハンドル
		strcpy( catlogIndex.Mes, saveSayData.Mes );			// 発言の標題
		// 既読スイッチの設定
		catlogIndex.kidoku= ' ';

//		PrintIndexData( catlogIndex );
//		PrintMessage( " を書き出しました" );

		fwrite( &catlogIndex, sizeof( struct CatlogIndex ), 1, IndexFpo );

		if ( saveSayData.InyouSw == YES ) {
			FileCopyInyou(
				MesNum,
				saveSayData.FileName,
				saveSayData.BStart,
				saveSayData.BEnd,
				CatlogFpo
			);
		} else {
			FileCopy(
				MesNum,
				saveSayData.FileName,
				saveSayData.BStart,
				saveSayData.BEnd,
				CatlogFpo
			);
		};

		if ( MesNum == BILL ) {
			catlog_fprintf( "日毎情報 (改行で表示  E:終了)" );
			catlog_fprintf( "" );
		};

		i++;
	};
	fclose( CatlogFpo );	CatlogFpo= NULL;
	fclose( IndexFpo );
	fclose( fp );
}

static	void	catlog_malloc()
{
	int		mes_sw;

	if ( catlog != NULL ) {
		free( catlog );			catlog= NULL;			max_catlog= 0;
	};

	if ( max_catlog == 0 ) {	mes_sw = YES;
	} else {					mes_sw = NO;
	};
	mes_sw= YES;
	max_catlog= mallocIdxSub(
#ifdef	TMENU
			65001L,
#else
			64L * 1024L / (long)sizeof( struct CATLOG ),
#endif
			(long)sizeof(struct CATLOG),
			(char **)(&catlog)
		);

#ifdef	TMENU
	mess_check {
		if ( mes_sw == YES ) {
			sprintf( YesNoMes, "\n１つの会議室で %d 個の発言を処理できます。",
				max_catlog
			);
			PrintMessage( YesNoMes );
		};
	};
#endif

}

/* 1993.12.11 新関数 */
/* 1995.5.23 削除
static	void	catlog_save_kaigi()
{
	FILE	*fpi, *fpo;
	char	*p;

	SetTmpDirFile( FileName, KAIGI_TMP_FILE_NAME);
	if ( ( fpi= fopen( FileName, "r")) == NULL )				return;
	// ファイル頭の無駄な行を読み飛ばす
	while ( fgets( str, LINE, fpi) != NULL ) {
		if ( strncmp( str, "-----会議室-----", 16) == 0 )	break;
	};
	forever {
		if ( fgets( ForumName, 20, fpi) == NULL )			break;
			without_crlf( ForumName);
		if ( isIDname( ForumName ) == YES ) {	MesNum= PATIO;
		} else {								MesNum= 0;
		};
		set_file_name( FileName, ForumName, MesNum, 0 );
		p= last_yen( FileName)+ 1;		*p = '\0';
		strcat( FileName , KAIGI_FILE_NAME );
		if ( (fpo = fopen( FileName , "w" ) ) == NULL ) {
			error_open_file( "catlog_save_kagi" );
			CATLOG_exit( 1 );
		};
		while( fgets( str, LINE, fpi) != NULL ) {
			if ( strncmp( str, "-----会議室-----", 16) == 0 )	break;
			fprintf( fpo, "%s", str);
		};
		fclose( fpo );
	};
	fclose( fpi);

	SetTmpDirFile( FileName, KAIGI_TMP_FILE_NAME);
	remove( FileName );
}
*/

/* 1994.1.4 新関数 */
/* 1995.5.23 削除
static	void	catlog_save_DL()
{
	FILE	*fpi, *fpo;
	char	*p;

	SetTmpDirFile( FileName, DL_TMP_FILE_NAME);
	if ( ( fpi= fopen( FileName, "r")) == NULL )				return;
	// ファイル頭の無駄な行を読み飛ばす
	while ( fgets( str, LINE, fpi) != NULL ) {
		if ( strncmp( str, "-----ＤＬ-----", 14) == 0 )		break;
	};
	forever {
		if ( fgets( ForumName, 20, fpi) == NULL )			break;
			without_crlf( ForumName);
		MesNum= LIB;
		set_file_name( FileName, ForumName, MesNum, 0 );
		p= last_yen( FileName)+ 1;		*p = '\0';
		strcat( FileName , DL_FILE_NAME );
		if ( (fpo = fopen( FileName , "w" ) ) == NULL ) {
			error_open_file( "catlog_save_kagi" );
			CATLOG_exit( 1 );
		};
		while( fgets( str, LINE, fpi) != NULL ) {
			if ( strncmp( str, "-----ＤＬ-----", 14) == 0 )	break;
			fprintf( fpo, "%s", str);
		};
		fclose( fpo );
	};
	fclose( fpi);

	SetTmpDirFile( FileName, DL_TMP_FILE_NAME);
	remove( FileName );
}
*/

// 1995.3.26 新規作成 GET_LINE2 に代わる関数
/* 1995.3.26 削除
static	char	*checkGetLine2()
{
	char	*p;

	if ( ( p= catlog_fgets() ) != NULL ) {
		checkSetLibNumber();
	};
	return( p );
}
***********************************************/

/* 1994.2.3 新関数 */
static	void	catlog_save_ID_TXT_sub2(const char *file )
{
	FILE	*fpo;

	if ( isCATLOGFile( file ) == 0 )			return;
	if ( MesNum != MAIL )						return;

#ifdef	TMENU
	mess_check {
		sprintf( YesNoMes, "\n<%s>からＩＤ.TMPを作ります", file );
		PrintMessage( YesNoMes );
	};
#endif

	/* そのファイルを読み込んでＩＤとハンドルをＩＤ.TMPに書き出す */
	SetTmpDirFile( FileName, ID_TMP_FILE_NAME);
	if ( ( fpo= fopen( FileName, "a" ) ) == NULL ) {
		error_open_file( "ＩＤ.TMPを書き出す(catlog)" );
		CATLOG_exit( 1 );
	};
	strcpy( FileName, file );
	if ( GetFileSize( FileName ) > 10L ) {
		if ( initial_check_pool( file ) == YES ) {
			forever {
				CPDS = PSP;
				GET_LINE2	break;								// 先読み
				if ( isMailFirstLine(PSP,NSP) != YES )		continue;
				strncpy( ForumName , PSP + 22 , 8 );
				ForumName[ 8 ] = '\0';
				strncpy( str, PSP + 3 , 17 );
				str[ 17 ] = '\0';
				fprintf( fpo, "%-8s %-17s\n", ForumName, str );
			};
			end_check_pool();
		};
	};
	fclose( fpo );
}

#ifdef	TMENU
#ifndef	CATLOG_EXG		// EXP 版の場合
//	###########################################################################
//	##### spawn ###############################################################
//	###########################################################################
#define	MAX_ARGV	20
static	char	*SpawnArgv[ MAX_ARGV + 1 ];
static	int		SpawnArgvP= 0;
#endif	// ! CATLOG_EXG
#endif	// TMENU

#ifdef	TMENU
#ifndef	CATLOG_EXG		// EXP 版の場合
void	SpawnTree( const char *mes )
{
	if ( SpawnArgvP >= MAX_ARGV ) {
		/* エラー */
		error_bug( "コマンドラインの引数の数が多すぎます(in SpawnTree)" );
	};
	SpawnArgv[ SpawnArgvP ] = malloc( strlen( mes ) + 2 );
	if ( SpawnArgv[ SpawnArgvP ] == NULL ) {
		/* メモリーが足りません エラー */
		error_bug( "メモリーが足りません(in SpawnTree)" );
	};
	strcpy( SpawnArgv[ SpawnArgvP++ ], mes);
	SpawnArgv[ SpawnArgvP ] = NULL;
}
#endif	// ! CATLOG_EXG
#endif	// TMENU

#ifdef	TMENU
#ifndef	CATLOG_EXG		// EXP 版の場合
void	collect_system( char *Command )
{
	int		i;

	mess_check {
		PrintMessage( "\n" );
		for ( i =0; i<SpawnArgvP; i++ ) {
			sprintf( YesNoMes, "%s ", SpawnArgv[i] );
			PrintMessage( YesNoMes );
		};
		PrintMessage( "を起動します" );
	};

	i = spawnvp( P_WAIT, Command, SpawnArgv );

	if ( i != 0 ) {
		/* _dos_errno に MS-DOS のエラーコードが入る */
		switch( errno ) {
/*
			case EFUNCTION:
				PrintMessage( "\n P_WAIT で起動していない" );
				break;
*/
			case ENOMEM:
				PrintMessage( "\nメモリーが不足した" );
				break;
			case ENOENT:
				PrintMessage( "\nパス名またはファイルが見つからない" );
				break;
			case E2BIG:
				PrintMessage( "\n引数リストが長すぎる" );
				break;
			case EACCES:
				PrintMessage( "\n EACCES エラーです" );
				break;
			case ENOEXEC:
				PrintMessage( "\n execフォーマットエラー" );
				break;
			default:
				sprintf( YesNoMes,"\nエラーです spawnvp=%d errno=%02x",
								i, errno
				);
				PrintMessage( YesNoMes );
				break;
		};
		PrintMessage( "\nエラーが発生しました 処理を中断します" );
		error_end( );
	};

	/* 確保していたメモリーを解放する */
	for ( i =0; i<SpawnArgvP; i++ )		free( SpawnArgv[i] );
	SpawnArgvP= 0;
}
#endif	// ! CATLOG_EXG
#endif	// TMENU

#ifdef	TMENU
#ifndef	CATLOG_EXG		// EXP 版の場合
//	###########################################################################
//	##### LHA を起動してファイルを圧縮する ####################################
//	###########################################################################
static	void	UpdateLzhFile_sub( const char *dir_name, const char *attr )
{
			int		done , cnt;
#ifdef	TMENU
			VECTOR		DTA;
			FMDTA		ffblk;
#else	// TMENU
	struct	_find_t		ffblk;
#endif	// TMENU
	struct	FileName { char name[16]; } *file;
			char	sub[ 16 ] , *p;

	/* FAPX が作ったファイルの数をかぞえる */
	strcpy( FileName , dir_name );		append_yen( FileName );
	strcat( FileName , attr );

//	sprintf( YesNoMes, "\n<%s>を圧縮します", FileName );
//	PrintMessage( YesNoMes );

	cnt = 0;
#ifdef	TMENU
	FM_SaveDta( &DTA );		FM_SetDta( &ffblk );
#endif	// TMENU
	done= FirstFile( FileName, 0 );			// ファイルを選択
	while ( ! done ) {
		/* FAPX風のファイル名のみ数える */
		if ( isFAPXfile( ffblk.name ) == YES ) cnt++;
		done = NextFile;
	};
#ifdef	TMENU
	FM_RecovDta( &DTA );
#endif	// TMENU

	if ( cnt == 0 )			return;					// ファイルがないので終了

	/* ファイルの名前を入れる領域を確保する */
	file=(struct FileName *)malloc( sizeof(struct FileName) * cnt );
	if ( file == NULL ) {
		StoreLZHSw = NO;
		DeleteOldFileSw = NO;		/* 今日より古いファイルの削除 OFF */
		error_return( "メモリーが足りないので圧縮は実行できません");
		return;
	};

	/* ファイルの名前（年月だけ）を入れる */
	strcpy( FileName , dir_name );		append_yen( FileName );
	strcat( FileName , attr );
	cnt = 0;
#ifdef	TMENU
	FM_SaveDta( &DTA );		FM_SetDta( &ffblk );
#endif	// TMENU
	done= FirstFile( FileName, 0 );			// ファイルを選択
	while ( ! done ) {
		/* FAPX風のファイル名のみ数える */
		if ( isFAPXfile( ffblk.name ) == YES ) {
			strcpy( str , ffblk.name );
			p = last_comma( str );
			if ( p != str ) *p = '\0';
			/*
				圧縮なしのモードならば、ファイル名の上４文字だけを取る
				圧縮ありのモードならば、ファイル名の上１文字だけを取る
				それ以外は、全ての名前を取る
			*/
			if ( FapxLogMode == 1 ) {			str[4]='\0';	/* 圧縮なし */
			} else if ( FapxLogMode == 2 ) {	str[1]='\0';	/* 圧縮あり */
			};
			strcpy( file[ cnt ].name , str );
			cnt++;
		};
		done = NextFile;
	};
#ifdef	TMENU
	FM_RecovDta( &DTA );
#endif	//TMENU

	/* ファイルの名前をソートする */
	qsort( (char *)file, cnt, sizeof( struct FileName ),
								(int (*)(const void *, const void *))strcmp );

	/* 同じファイル名を除く */
	/* 残ったファイル名に対して LHA.EXE を起動する */
	for ( done = 0 ; done < cnt ; done ++ ) {
		SpawnTree( "LHA.EXE" );
		SpawnTree( "u" );
		strcpy( str, dir_name );					// /log/
		append_yen( str );
		if ( FapxLogMode == 2 ) {					// 圧縮あり
			strcpy( sub , ToDay );
			sub[ 2 ] = '\0';						// 年だけ入れる
			strcat( str, sub );
		};
		strcat( str, file[done].name );				// /log/9208
		SpawnTree( str );							// lha u /log/

		strcpy( str, dir_name );					// /log/
		append_yen( str );
		strcat( str, file[done].name );				// /log/9208
		strcat( str, attr );						// /log/9208/???.log
		SpawnTree( str );
		collect_system( "LHA.EXE" );
		while(strcmp(file[done].name,file[done+1].name)==0) done++;
	};

	/* 確保した領域を解放する */
	free( file );
}
#endif	// ! CATLOG_EXG
#endif	// TMENU

#ifdef	TMENU
#ifndef	CATLOG_EXG		// EXP 版の場合
static	void	UpdateLzhFile( const char *dir_name )
{
	char	attr[ 8 ];
	char	subDir[ MAX_FILENAME_LEN ], *p1;

	strcpy( subDir, dir_name );		append_yen( subDir );
	p1= last_yen( subDir );
	if ( *(p1+1) == '\0' ) {	*p1= '\0';	p1= last_yen( subDir );
	};
	strcpy( subDir, p1 );

	if ( FapxLogMode == 2 ) {
		/************************************/
		/* FAPX のログ保存モードは 圧縮あり */
		/************************************/
		UpdateLzhFile_sub( dir_name , "*.eml" );
		UpdateLzhFile_sub( dir_name , "*.up"  );
		UpdateLzhFile_sub( dir_name , "*.res" );
		UpdateLzhFile_sub( dir_name , "*.npb" );
		UpdateLzhFile_sub( dir_name , "*.log" );
		return;
	};

	/******************************************/
	/* FAPX のログ保存モードは 圧縮なしモード */
	/******************************************/
	if (	strcmp( subDir , "NIFMAIL" ) == 0
	||		strcmp( subDir , "SENDMAIL" ) == 0
	) {
		strcpy( attr , "*.eml" );						/* /log/9208*.eml */
	} else if ( strcmp( subDir , "NAPMAIL" ) == 0 ) {
		strcpy( attr , "*.npb" );						/* /log/9208*.npb */
	} else if ( strcmp( subDir , "WEATHER" ) == 0 ) {
		strcpy( attr , "*.npb" );						/* /log/9208*.npb */
	} else {
		UpdateLzhFile_sub( dir_name , "*.up"  );
		UpdateLzhFile_sub( dir_name , "*.res" );
		strcpy( attr , "*.log" );						/* /log/9208*.log */
	};
	UpdateLzhFile_sub( dir_name , attr );
}
#endif	// ! CATLOG_EXG
#endif	// TMENU

static	void	(*CatlogFindFirstRun)(const char *file, const char *ff_name);
static	void	CatlogFindfirstLoop( const char *path )
{
			int		done;
#ifdef	TMENU
			VECTOR		DTA;
			FMDTA		ffblk;
#else	// TMENU
	struct	_find_t		ffblk;
#endif	// TMENU
			char	f_name[ MAX_FILENAME_LEN ];

#ifdef	TMENU
#ifndef	CATLOG_EXG		// EXP 版の場合
	if ( StoreLZHSw == YES )	UpdateLzhFile( path );
#endif	// ! CATLOG_EXG
#endif	// TMENU

#ifdef	TMENU
	mess_check {
		sprintf( YesNoMes, "\n<%s>のディレクトリを調べます。", path );
		PrintMessage( YesNoMes );
	};
#endif

	strcpy( f_name , path );		append_yen( f_name );
	strcat( f_name , "*.*" );								// 全ファイルを検索

#ifdef	TMENU
	FM_SetDta( &ffblk );
#endif	// TMENU
	done= FirstFile( f_name, FA_DIREC );			// ファイルを選択
	while ( ! done ) {
		strcpy( f_name , path );	append_yen( f_name );
		strcat( f_name , ffblk.name );
		if ( ( ATTR & FA_DIREC ) == FA_DIREC ) {
#ifdef	TMENU
		FM_SaveDta( &DTA );
#endif	// TMENU
			if (	strcmp( ffblk.name , "." ) != 0
			&&		strcmp( ffblk.name , ".." ) != 0
			&&		isWithoutSearchFile( f_name, ffblk.name ) == NO
//			&&		isSearchFile( f_name, ffblk.name ) == YES
			) {
				CatlogFindfirstLoop( f_name );
			};
		} else {
			/* ファイル名 */
			(*CatlogFindFirstRun)( f_name , ffblk.name );
		};
#ifdef	TMENU
		FM_RecovDta( &DTA );
#endif	// TMENU
		if ( CheckAbortSw == YES )								break;
		done = NextFile;
	};


#ifndef	TMENU	// Win 版
	sprintf( YesNoMes, "\n<%s>を調べ終わりました", path );
	PrintMessage( YesNoMes );
#endif
}

void	CatlogFindFirst(
	const char *path,
	void (*sub)( const char *file, const char *ff_name )
) {
	CatlogFindFirstRun = sub;	CatlogFindfirstLoop( path );
}

static	void	(*CatlogFindFirstRun2)(const char *file );
static	void	CatlogFindFirstLoop2( const char *path )
{
			int		done;
#ifdef	TMENU
			VECTOR		DTA;
			FMDTA		ffblk;
#else	// TMENU
	struct	_find_t		ffblk;
#endif	// TMENU
			char	f_name[ MAX_FILENAME_LEN ];

	strcpy( f_name , path );		append_yen( f_name );
	strcpy( catlog_findfirst_path, f_name );
	strcat( f_name , "*.*" );	// 全ファイルを検索

#ifdef	TMENU
	FM_SetDta( &ffblk );
#endif	// TMENU
	done= FirstFile( f_name, FA_DIREC );			// Dir を選択
	while ( ! done ) {
		strcpy( f_name , path );	append_yen( f_name );
		strcat( f_name , ffblk.name );
#ifdef	TMENU
		FM_SaveDta( &DTA );
#endif	// TMENU
		if ( ( ATTR & FA_DIREC ) == FA_DIREC ) {
			if (	strcmp( ffblk.name , "." ) != 0
			&&		strcmp( ffblk.name , ".." ) != 0
			&&		isWithoutSearchFile( f_name, ffblk.name ) == NO
//			&&		isSearchFile( f_name, ffblk.name ) == YES
			) {
				CatlogFindFirstLoop2( f_name );
			};
		} else {
			/* ファイル名 */
			(*CatlogFindFirstRun2)( f_name );
		};
#ifdef	TMENU
		FM_RecovDta( &DTA );
#endif
		done = NextFile;
	};
}

void	CatlogFindFirst2(
	const char *path,
	void (*sub)( const char *file )
) {
	CatlogFindFirstRun2 = sub;	CatlogFindFirstLoop2( path );
}

/* 1994.2.3 新関数 */
static	void	catlog_save_ID_TXT_sub()
{
	FILE	*fpi;
	char	*p;
#ifdef	TMENU
			VECTOR		DTA;
			FMDTA		ffblk;
#else	// TMENU
	struct	_find_t		ffblk;
#endif
	char	path[ 128 ];

	/* 1994.3.5 追加 ディレクトリが無ければ終了 */
	strcpy( path, OutDir );		append_yen( path );
	strcat( path, "NIFMAIL" );
#ifdef	TMENU
	FM_SaveDta( &DTA );		FM_SetDta( &ffblk );
#endif
	if ( FirstFile( path, FA_DIREC ) != 0 ) {
#ifdef	TMENU
		mess_check {
			sprintf( YesNoMes, "\n<%s>はありません", path);
			PrintMessage( YesNoMes );
		};
		FM_RecovDta( &DTA );
#endif	// TMENU
		return;
	};
#ifdef	TMENU
	FM_RecovDta( &DTA );
#endif


	/* 1994.2.2 追加
			OutPath の下の NIFMAIL の下に ID_HANDLE_FILE_NAME はある？
	*/
	MesNum= MAIL;	strcpy( ForumName, "UN_KNOWN" );
	set_file_name( FileName, ForumName, MesNum, 0 );
	p= last_yen( FileName)+ 1;		*p = '\0';
	strcat( FileName , ID_HANDLE_FILE_NAME );
	if ( ( fpi= fopen( FileName, "r" ) ) != NULL ) {
		/* あるので終了 */
		fclose( fpi );	return;
	};
	/* ないので作る */
	strcpy( path, OutDir );		append_yen( path );
	strcat( path, "NIFMAIL\\" );

#ifdef	TMENU
	mess_check {
		sprintf( YesNoMes, "\n<%s>からＩＤ.TMPを作ります", path );
		PrintMessage( YesNoMes );
	};
#endif

	CatlogFindFirst2( path, catlog_save_ID_TXT_sub2 );
}

#define	MAX_ID	300

/* 1994.2.3 新関数 */
static	void	catlog_save_ID_TXT()
{
	FILE	*fpi, *fpo;
	char	*p, *pe;
	int		i, j, sw, maxID;
	char	*ID[ MAX_ID ], *Handle[ MAX_ID ];

	/* 1994.2.2 追加
			OutPath の下の NIFMAIL の下に ID_HANDLE_FILE_NAME はある？
	*/
	/* なければ、作る */
	catlog_save_ID_TXT_sub();

	/* TmpDir の下に ID_TMP_FILE_NAME はある？ */
	SetTmpDirFile( FileName, ID_TMP_FILE_NAME);
	if ( ( fpi= fopen( FileName, "r")) == NULL )				return;

	/*	ＩＤ.TMP からIDとハンドルを読み込む
			ただし、同じハンドルは読み込まない
	*/
	maxID= 0;
	while ( fgets( str, LINE, fpi) != NULL ) {
		if (	*str == '\0'
		||		*str == '\n'
		)						continue;
		strncpy( ForumName , str    ,  8 );		ForumName[  8]= '\0';
		strncpy( ForumName2, str + 9, 17 );		ForumName2[17]= '\0';
		sw= NO;
		for ( i=0; i<maxID; i++ ) {
			if (	strcmp( ID[i], ForumName ) == 0
			&&		strcmp( Handle[i], ForumName2 ) == 0
			) {
				/* ＩＤとハンドルが一致した */
				sw= YES;	break;
			};
		};
		if ( sw == NO ) {
			if ( maxID >= MAX_ID ) {
				error_bug( "登録するＩＤの数が多すぎます" );
			};
			/* 一致するものはなかった */
			ID[ maxID ] =		(char *) malloc( 10 );
			Handle[ maxID ] =	(char *) malloc( 20 );
			strcpy( ID[ maxID ], ForumName );
			/* ハンドル名を記録する */
			strcpy( Handle[ maxID ], ForumName2 );
			maxID++;
		};
	};
	fclose( fpi);

	if ( maxID > 0 ) {
		for ( i=0; i<maxID; i++ ) {
			/* ハンドル名の長さを 17 バイトに揃える */
			p= Handle[i];	pe= p + 17;
			while ( *p ) p++;
			while ( p < pe ) *p++ = ' ';
			*p= '\0';
		};
		SetTmpDirFile( FileName, ID_TMP_FILE_NAME);
		if ( ( fpo= fopen( FileName, "w")) == NULL ) {
			error_open_file( "ＩＤ.TMPを書き出す(catlog_save_ID_TXT)" );
			CATLOG_exit( 1 );
		};
		/* TMPのデータが存在する */
		MesNum= MAIL;	strcpy( ForumName, "UN_KNOWN" );
		set_file_name( FileName, ForumName, MesNum, 0 );
		p= last_yen( FileName)+ 1;		*p = '\0';
		strcat( FileName , ID_HANDLE_FILE_NAME );
		if ( ( fpi= fopen( FileName, "r")) == NULL ) {
			/*  ID_HANDLE_FILE_NAME  がないので作る */
			for ( i=0; i<maxID; i++ ) {
				if ( *ID[i] != '\0' ) {
					fprintf( fpo, "%-8s %-17s", ID[i], Handle[i] );
					/* 同じ ID の異なるハンドル名を登録する */
					for ( j= i+1; j<maxID; j++ ) {
						if ( strcmp( ID[i], ID[j] ) == 0 ) {
							fprintf( fpo, " %-17s", Handle[j] );
							*ID[j] = *Handle[j] = '\0';
						};
					};
					fprintf( fpo, "\n" );
				};
			};
		} else {
			/*  ID_HANDLE_FILE_NAME  があるので それを読み込みながら書き出す */
			while ( fgets( str, LINE, fpi) != NULL ) {
				without_crlf( str );
				pe = str + strlen( str );
				sscanf( str, "%8s", ForumName );
				for ( i=0; i<maxID; i++ ) {
					/* ID は同じ？ */
					if (	*ID[i] != '\0'
					&&		strcmp( ForumName, ID[i] ) == 0
					) {
						/* Handle[i] は登録済？ */
						p= str + 8;		/* first Handle */
						sw= NO;
						while ( p < pe ) {
							p= skip_space( p );
							if ( p >= pe )		break;
							if ( strncmp( p, Handle[i], 17 ) == 0 ) {
								/* 一致するものがあった そのデータは削除 */
								*ID[i] = *Handle[i] = '\0';
								sw= YES;	break;
							} else {
								p += 17;
							};
						};
						if ( sw == NO ) {
							strcat( str, Handle[i] );
							/* 登録したので そのデータは削除 */
							*ID[i] = *Handle[i] = '\0';
						};
					};
				};
				fprintf( fpo, "%s\n", str );
			};
			fclose( fpi );
			/* 新しい人からのメールを登録する */
			for ( i=0; i<maxID; i++ ) {
				/* 未登録？ */
				if ( *ID[i] != '\0' ) {
					fprintf( fpo, "%-8s %-17s\n", ID[i], Handle[i] );
				};
			};
		};
		fclose( fpo );

		/* ＩＤ.TMP を  ID_HANDLE_FILE_NAME  にコピーする */
		SetTmpDirFile( FileName, ID_TMP_FILE_NAME);
		if ( ( fpi= fopen( FileName, "r")) == NULL ) {
			error_open_file( "ＩＤ.TMPを読み込む" );
			CATLOG_exit( 1 );
		};
		MesNum= MAIL;	strcpy( ForumName, "UN_KNOWN" );
		set_file_name( FileName, ForumName, MesNum, 0 );
		p= last_yen( FileName)+ 1;		*p = '\0';
		strcat( FileName , ID_HANDLE_FILE_NAME );
		if ( ( fpo= fopen( FileName, "w")) == NULL ) {
			error_open_file( "「ＩＤ→ハンドル」ファイルを書き出す" );
			CATLOG_exit( 1 );
		};
		while ( fgets( str, LINE, fpi) != NULL ) {
			fprintf( fpo, "%s", str );
		};
		fclose( fpi );	fclose( fpo );

		/* 確保した領域を開放する */
		for( i=0; i<maxID; i++ ) {		free( ID[i] );	free( Handle[i] );
		};
	};

	SetTmpDirFile( FileName, ID_TMP_FILE_NAME);
	remove( FileName );
}

/*********************************************************************/
/***************************  第３段階  ******************************/
/*********************************************************************/

static	int		is_clip_index( FILE *fp, const char *trg )
{
	fseek( fp, 0L, SEEK_SET );
	while( fread( &catlogIndex, sizeof(struct CatlogIndex), 1, fp ) == 1 ) {
		if ( catlogIndex.MesNum != CLIP )				continue;
		if ( strcmp( catlogIndex.Mes, trg ) == 0 )		return( YES );
	};
	return( NO );
}

static	void	catlog_clip_main( const char *file )
{
	char	*p;
	FILE	*IndexFpo ;
	char	fileName[ MAX_FILENAME_LEN ];

	*ForumNameLineSub = '\0';

	// インデックス・ファイルのオープン
	set_index_file_name( fileName, "CLIP" );		/* file.c */
	if ( ( IndexFpo = fopen( fileName , "ab+" ) ) == NULL ) {
		er_open( fileName, 1, "catlog_clip_append_index" );
	};
	catlogIndex.MesNum	= CLIP;
	strcpy( catlogIndex.ForumName, "CLIP" );
	catlogIndex.SayDate = catlogIndex.SayId = 0L;
	catlogIndex.SayNum  = catlogIndex.ComNum = 0;
	*catlogIndex.Handle = '\0';

	/* 入力ファイルのオープン */
	CatlogFpi = fopen( file , "rb" );
	while( fread(&saveSayData,sizeof(struct SaveSayData),1,CatlogFpi) == 1) {
		// 登録済かチェック						登録済なら読み飛ばす
		p= saveSayData.ForumNameLine + 3 ;
		if ( is_clip_index( IndexFpo, p ) == YES )			continue;

		/* CatlogFpo をオープンする */
		if ( OpenAndCheckNewFile( ) == YES ) {
			Write1stLine(
				saveSayData.ForumNameLine, saveSayData.ForumNameLineSub
			);
		};

		catlogIndex.seek= ftell( CatlogFpo );
		catlogIndex.FileNum = FileNum;

		/* インデックスに登録する */
		StrCut( p, 44 );		strcpy( catlogIndex.Mes, p );
		// 既読スイッチの設定
		catlogIndex.kidoku= ' ';
		fseek( IndexFpo, 0L, SEEK_END );
		fwrite( &catlogIndex, sizeof( struct CatlogIndex ), 1, IndexFpo );

		// データを書き込む
		FileCopy(
			MesNum,
			saveSayData.FileName,
			saveSayData.BStart,
			saveSayData.BEnd,
			CatlogFpo
		);
		fclose( CatlogFpo );	CatlogFpo= NULL;
		HatsugenSu++;
	};
	fclose( CatlogFpi );
	fclose( IndexFpo );
}

static	int		max_lib;
static	int		lib_num;

static	struct	Collect_LIB	*collect_lib;

static	void	catlog_collect_lib_load1( )
{
		int		lib_num;
		char	forum[ 48 ];

	set_file_name( FileName, ForumName, MesNum, 0 );
	if ( GetFileSize( FileName ) <= 0L ) return;
	if ( initial_check_pool( FileName ) == NO )					return;
	GET_LINE2 {		end_check_pool();	return;	};	/* COLLECT_ID_LIB:xxx */
	lib_num = 0;
	forever {
		CPDS = PSP;
		/* フォーラム名のストア */
		GET_LINE2	break;			present_str_copy( str );
		if ( PSL == 0 )	continue;	/* 読み飛ばし（空行） */
		IfMatchStrYes( "FORUM:" ) {
			strcpy( forum , str + 6 );
			GET_LINE2	break;		present_str_copy( str );
		};
		IfMatchStrYes( "LIB:" ) {
			/* LIB 番号のストア */
			lib_num = atoi(PSP+4);
			GET_LINE2	break;		present_str_copy( str );
		};
		/* LIB リストのストア */
		strcpy( collect_lib[ lib_num ].forum , forum );	/* FORUM: */
		collect_lib[ lib_num ].lib_num = lib_num;
		strcpy( collect_lib[ lib_num ].line , str );
		lib_num++;
		if ( max_lib <= lib_num ) {
			PrintMessage(	"\nこのＩＤの人はＤＬに沢山のデータを登録していて"
				"これ以上処理できません。"
			);
			break;
		};
	};
	end_check_pool();
}

static	void	catlog_collect_lib_load2( const char *file )
{
	FILE	*fpi1, *fpi2;

	if ( ( fpi1 = fopen( file , "rb" ) ) == NULL ) {
		er_open( file, 0, "catlog_collect_lib_load2" );
	};
	while ( fread( &saveSayData, sizeof(struct SaveSayData), 1, fpi1 ) == 1 ) {
		strcpy( collect_lib[ lib_num ].forum, saveSayData.ForumName );
		collect_lib[ lib_num ].lib_num = saveSayData.SayNum;	// LIB の番号

		// データを collect_lib[ lib_num ].line に入れる
		if ( ( fpi2 = fopen( saveSayData.FileName, "r" ) ) == NULL ) {
			er_open( saveSayData.FileName, 0, "catlog_collect_lib_load2" );
		};
		fseek( fpi2, saveSayData.BStart, SEEK_SET );
		while ( ftell( fpi2 ) < saveSayData.BEnd ) {
			fgets( str , 1024, fpi2 );						// 先読み
			if ( atoi( str ) > 0 ) {
				without_crlf( str );
				StrCut( str, 80 );							// 1行80文字にする
				strcpy( collect_lib[ lib_num ].line , str );
				lib_num++;
				if ( max_lib <= lib_num ) {
					PrintMessage(
						"\nこのＩＤの人はＤＬに沢山のデータを登録していて"
						"これ以上処理できません。");
					break;
				};
			};
		};
		fclose( fpi2 );
	};
	fclose( fpi1 );
}

/**********************************/
/* CCLS : catlog_collect_lib_sort */
/**********************************/
int	CCLS_cmp1( const void *p11 , const void *p21 )
{
	const struct Collect_LIB *p1 = (const struct Collect_LIB *)p11;
	const struct Collect_LIB *p2 = (const struct Collect_LIB *)p21;

	return( strcmp( p1->forum , p2->forum ) );
}

int	CCLS_cmp2( const void *p11 , const void *p21 )
{
	const struct Collect_LIB *p1 = (const struct Collect_LIB *)p11;
	const struct Collect_LIB *p2 = (const struct Collect_LIB *)p21;

	return( p1->lib_num - p2->lib_num );
}

int	CCLS_cmp3( const void *p11 , const void *p21 )
{
	const struct Collect_LIB *p1 = (const struct Collect_LIB *)p11;
	const struct Collect_LIB *p2 = (const struct Collect_LIB *)p21;

	/* 大きいものから並べる */
	return( strcmp( p2->line , p1->line ) );
}

/**********************/
/* LIB リストでソート */
/**********************/
static	void	catlog_collect_lib_sort2( int s , int e )
{
	int		k , l;

	k = s;
	while ( k + 1 < e ) {
		l = k + 1;
		while ( collect_lib[ k ].lib_num == collect_lib[ l ].lib_num ) {
			l++;
			if ( e <= l )	break;
		};
		if ( k + 1 < l ) {
			qsort(
				(char *)collect_lib + k * sizeof( struct Collect_LIB ),
				l - k,
				sizeof( struct Collect_LIB ) ,
				CCLS_cmp3
			);
		};
		k = l;
	};
}

static	void	catlog_collect_lib_sort( )
{
	int		i , j;

	/* フォーラム名でソート */
	qsort( collect_lib , lib_num , sizeof(struct Collect_LIB ) , CCLS_cmp1 );
	/* LIB 番号でソート */
	i = 0;
	while ( i + 1 < lib_num ) {
		j = i + 1;
		while ( strcmp(collect_lib[i].forum , collect_lib[j].forum)==0) {
			j++;
			if ( lib_num <= j )	break;
		};
		if ( i + 1 < j ) {		/* フォーラム名が同じ物がある */
			/************************/
			/* LIB 番号でソートする */
			/************************/
			qsort( (char *)collect_lib + i * sizeof( struct Collect_LIB ) ,
				j - i,
				sizeof( struct Collect_LIB ) ,
				CCLS_cmp2
			);
			/**********************/
			/* LIB リストでソート */
			/**********************/
			catlog_collect_lib_sort2( i , j );
		};
		i = j;
	};
}

static	void	catlog_collect_lib_delete( )
{
	int		i;

	for ( i = 0 ; i < lib_num - 1 ; i++ ) {
		if (	strcmp( 
					collect_lib[ i     ].forum ,
					collect_lib[ i + 1 ].forum
				) == 0
		&&	collect_lib[ i ].lib_num == collect_lib[ i + 1 ].lib_num
		&&	atoi( collect_lib[ i ].line ) == atoi( collect_lib[ i + 1 ].line )
		) {
			/* 小さい方を削除する */
			*(collect_lib[ i ].forum) = *(collect_lib[ i ].line) = '\0';
			collect_lib[ i ].lib_num = 0;
		};
	};
}

static	void	catlog_collect_lib_save( )
{
	int		i , last_lib_num;
	FILE	*fpo;
	char	str1[ 40 ] , last_forum[ 12 ];

	set_file_name( FileName, ForumName, MesNum, 0 );
	if ( (fpo = fopen( FileName , "w" ) ) == NULL ) {
		error_open_file( "COLLECT_ID_LIBで整理したデータを記録する所" );
		error_end();
	};
	sprintf( str1 , "COLLECT_ID_LIB:%s " , SayId );
	set_catlog_file_line_1( str1 );								/* sub.c */
	fprintf( fpo , "%s\n" , str );		/* １行目 */
	strcpy( last_forum , "(null)" );	last_lib_num = 0;
	for ( i = 0 ; i < lib_num ; i++ ) {
		if ( collect_lib[ i ].lib_num != 0 ) {
			if ( strcmp( last_forum , collect_lib[ i ].forum ) != 0 ) {
				fprintf( fpo , "\nFORUM:%s\n" , collect_lib[ i ].forum );
				fprintf( fpo , "LIB:%d\n" ,     collect_lib[ i ].lib_num );
				strcpy( last_forum , collect_lib[ i ].forum );
				last_lib_num = collect_lib[ i ].lib_num;
			} else if ( last_lib_num != collect_lib[ i ].lib_num ) {
				fprintf( fpo , "\nLIB:%d\n" ,   collect_lib[ i ].lib_num );
				last_lib_num = collect_lib[ i ].lib_num;
			};
			fprintf( fpo , "%s\n" ,     collect_lib[ i ].line );
			HatsugenSu++;		/* 1つのファイルの発言の数 */
		};
	};
	fclose( fpo );
}

/****************************/
/* Collect_LIB の処理の入口 */
/****************************/
void	catlog_collect_lib( const char *file )
{
	int		i;

	max_lib= mallocIdxSub(
#ifdef	TMENU
			1000L,
#else
			64L * 1024L / (long)sizeof( struct Collect_LIB ),
#endif
			(long)sizeof(struct Collect_LIB),
			(char **)(&collect_lib)
		);
	for ( i = 0 ; i < max_lib ; i++ ) collect_lib[ i ].lib_num = 0;
	lib_num = 0;
	catlog_collect_lib_load1( );			/* 登録済のデータをロードする */
	catlog_collect_lib_load2( file );		/* TMP ファイルからﾃﾞｰﾀをﾛｰﾄﾞする */
	catlog_collect_lib_sort( );				/* ソートする */
	catlog_collect_lib_delete( );			/* 重複しているものは削除する */
	catlog_collect_lib_save( );		/* 残ったデータを登録する */
	free( collect_lib );					/* 領域を開放する */
}

/**************************************************************************/
/**************************************************************************/
/**************************************************************************/

static	struct	Lib_List	*CatlogLibList;

static	void	catlog_lib_over_error()
{
	PrintMessage(	"\nＤＬに登録されているデータの登録番号が"
			"大きすぎて処理できません。"
	);
	PrintMessage(	"\nできれば、メモリーを増設して下さい。" );
//	PrintMessage(	"\nすみませんが、NIFTY ID:NAA02244までお知らせ下さい。" );
	error_end();
}

/********************/
/* LIB をロードする */
/********************/
static	void	catlog_lib_load( )
{
	int		lineNum;

	set_file_name( FileName, ForumName, MesNum, SayNum );
	if ( GetFileSize( FileName ) <= 0L ) return;

	if ( initial_check_pool( FileName ) == YES ) {
		GET_LINE2 {	end_check_pool();	return;	};	/* FORUM:xxx LIB:xx */
		GET_LINE2 {	end_check_pool();	return;	};	/* ＜……＞  FRAV */
		if ( isLIBLine() == NO ) {
			if ( *ForumNameLine=='\0') present_str_copy( ForumNameLine );
			while ( isLIBLine() == NO )	{
				GET_LINE2	break;
			};
		};
		forever {
			CPDS = PSP;
			lineNum = atoi( PSP );
			if ( lineNum < 0 ) {
				present_str_print();
				if (get_yesno( "← ライブラリーの番号が？？？" ) != YES ) {
					break;
				};
				continue;
			};
			lineNum = atoi( PSP );
			if ( max_lib <= lineNum ) catlog_lib_over_error();
			present_str_copy( CatlogLibList[ lineNum ].old );
			GET_LINE2	break;	/* 先読み */
		};
		end_check_pool();
	};
}

static	void	prMesInputLine( FILE *fpo )
{
	fprintf( fpo ,
		"1:お知らせ            *:掲示板      3:電子会議\n"
		"4:データライブラリ    5:会員情報    6:リアルタイム会議\n"
		"7:SYSOP 宛メール      8:オプション  E:終了\n"
	);
}

static	int		isEQULIBList( int New , int old )
{
	char	*p_new , *p_old;

	p_new = CatlogLibList[ New ].New;	p_old = CatlogLibList[ old ].old;
	if ( *p_new =='\0' || *p_old == '\0' )						return( NO );
/****************************************************************************
＞          1         2         3         4         5
＞ 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234
＞ 343  NAA02244 92/06/08   57903   19 B CATLOG06.EXE NIFTY通信ログ編集ﾌﾟﾛｸﾞﾗﾑ
*****************************************************************************/
	/* ID */
	if ( strncmp( p_new +  6 , p_old +  6 ,  8 ) != 0 )			return( NO );
	/* 登録日 */
	if ( strncmp( p_new + 15 , p_old + 15 ,  8 ) != 0 )			return( NO );
	/* サイズ */
	if ( strncmp( p_new + 24 , p_old + 24 ,  7 ) != 0 )			return( NO );
	/* データ名 */
	if ( strcmp(  p_new + 39 , p_old + 39 ) != 0 )				return( NO );
	return( YES );
}

#define	LARGE_OLD	1
#define	LARGE_NEW	2

static	int
catlog_lib_change_sub( int new_max, int new_min, int old_max, int old_min )
{
	int		i , j;
	int		l_new , l_old , large_new , large_old;
	char	*p_new , *p_old;

	large_new = large_old = 0;
	for ( i = new_max ; i >= new_min ; i-- ) {
		p_new = CatlogLibList[ i ].New;
		if ( *p_new != '\0' ) {
			for ( j = old_max ; j >= old_min ; j-- ) {
				p_old = CatlogLibList[ j ].old;
				if (	*p_old != '\0'
				&&		i != j
				&&		isEQULIBList( i , j ) == YES
				) {
					/* 一致する物があった → 登録番号が変わった */
					/* 参照数のチェック */
					l_new = atoi( p_new + 24 );
					l_old = atoi( p_old + 24 );
					if ( l_new < l_old ) {				large_old++;
					} else if ( l_new > l_old ) {		large_new++;
					};
				};
			};
		};
	};
	if ( large_new < large_old )	return( LARGE_OLD );
	if ( large_new > large_old )	return( LARGE_NEW );
	/* 一致する物が１つもない場合 */
	return( LARGE_NEW );
}

static	void	catlog_lib_change()
{
	int		i , sw;
	int		New , old;
	int		new_max , old_max , new_min , old_min;
	char	*p_new , *p_old;

	/************************************************/
	/* new_max , old_max , new_min , old_min の設定 */
	/************************************************/
	new_min = old_min = 0;
	for ( i = 1 ; i < max_lib - 1 ; i++ ) {
		if ( *CatlogLibList[ i ].New != '\0' ) {	new_min = i;	break;	};
	};
	for ( i = 1 ; i < max_lib - 1 ; i++ ) {
		if ( *CatlogLibList[ i ].old != '\0' ) {	old_min = i;	break;	};
	};

	/* 古い方のリストが無い場合は 終了 */
	if ( old_min == 0 )		return;

	new_max = old_max = max_lib - 1;
	for ( i = max_lib - 1 ; i >= 0 ; i-- ) {
		if ( *CatlogLibList[ i ].New != '\0' ) {	new_max = i;	break;	};
	};
	for ( i = max_lib - 1 ; i >= 0 ; i-- ) {
		if ( *CatlogLibList[ i ].old != '\0' ) {	old_max = i;	break;	};
	};

	/* New と old とで、どちからが新しいか調べる */
	sw = strncmp(	CatlogLibList[ new_max ].New + 15 ,	/* 登録年月日 */
					CatlogLibList[ old_max ].old + 15 ,
					8
	);
	if ( sw < 0 ) {			sw = LARGE_OLD;
	} else if ( 0 < sw ) {	sw = LARGE_NEW;
	} else {	/* 登録年月日が等しい場合 */
		/* New を元に、登録番号が変更されていないか調べる */
		sw = LARGE_NEW;
		for ( i = new_max ; i >= new_min ; i-- ) {
			p_new = CatlogLibList[ i ].New;
			p_old = CatlogLibList[ i ].old;
			if ( *p_new != '\0' && *p_old != '\0' ) {
				if ( isEQULIBList( i , i ) == NO ) {
					/* 登録番号の変更があった */
					sw= catlog_lib_change_sub(new_max,new_min,old_max,old_min);
					break;
				} else {
					/* 登録番号の変更はない */
					/* 一致 → 参照数によって新しいリストの方を決める */
					New = atoi( p_new + 24 );	old = atoi( p_old + 24 );
					if ( New < old ) {				sw = LARGE_OLD;	break;
					} else if ( New > old ) {		sw = LARGE_NEW;	break;
					};
				};
			};
		};
	};

	/* リストを New に集める */
	if ( sw == LARGE_OLD ) {
		/* New の部分消去 */
		for ( i=max_lib -1 ; i>old_max ; i-- ) *CatlogLibList[i].New='\0';
		/* old の値を New へコピー */
		for ( i = old_max ; i >= old_min ; i-- ) {
			strcpy(CatlogLibList[i].New,CatlogLibList[i].old);
		};
		/* 未ダウンリストのコピー ← 不用 */
	};
}

static	int		Catlog3LibSave( )
{
	int		i, old_start;
	FILE	*fpo;

	catlog_lib_change();

	set_file_name( FileName, ForumName, MesNum, SayNum );

	if ( (fpo = fopen( FileName, "w" ) ) == NULL ) {
		sprintf(str,"\n Catlog3LibSave 書き込みが出来ません<%s>",FileName);
		error_return( str );	return( NO );
	};
	fprintf( fpo, "FORUM:%s LIB:%d\n", ForumName, SayNum);
	fprintf( fpo, "%s\n", ForumNameLine);

	/**********************************/
	/* 下の３行追加        1992.12.29 */
	/* 細谷　健　さん（HCD01017）より */
	/**********************************/
	prMesInputLine( fpo );

	/************************************/
	/* 下の２行はＮＩＦＰへの対応である */
	/************************************/
	fprintf( fpo , "＞LIB %d\n" , SayNum );
	/* 1994.2.13 １行追加 */
	fprintf( fpo, "%s\n", ForumNameLineSub);
	fprintf( fpo , "番号  ID       登録日付 バイト  参照   データ名\n" );

	/* 1994.2.12 追加 古いデータを残すようにする為の処理 */
	old_start= 0;
	for ( i=1; i<max_lib-1 ; i++ ) {
		if ( *CatlogLibList[ i ].New != '\0' ) {
			old_start= i;
			break;
		};
	};

	for ( i = max_lib - 1 ; i >= 0 ; i-- ) {
		if ( *CatlogLibList[ i ].New != '\0' ) {
				/* 新しい方にある場合は書き出す */
				fprintf( fpo , "%s\n" , CatlogLibList[ i ].New );
				HatsugenSu++;
		/* 1994.2.12 追加 古いデータを残すようにする為の処理 */
		} else {
			/* 新しい方にない場合は 削除されたデータであるか調べる */
			if (	i < old_start
			&&		*CatlogLibList[ i ].old != '\0'
			) {
				/* 古い方にしか無いデータであるので 書き出す */
				fprintf( fpo , "%s\n" , CatlogLibList[ i ].old );
				HatsugenSu++;
			};
		};
	};
	fclose( fpo );		return( YES );
}

/********************/
/* LIB の処理の入口 */
/********************/
static	int		catlog_lib_mes_sw = NO;
void	Catlog3Lib( const char *file )
{
		int		sw , i , lineNum;
		FILE	*fpi1, *fpi2;
		char	str[ 1024 ], *p;

	i= mallocIdxSub(20L * 1024L / 1L, 1L, &p );
	max_lib= mallocIdxSub(
#ifdef	TMENU
			20000L,
#else
			64L * 1024L / (long)sizeof( struct Lib_List ),
#endif
			(long)sizeof(struct Lib_List),
			(char **)(&CatlogLibList)
		);
	if (	catlog_lib_mes_sw == NO
	&&		Display == YES
	) {
		catlog_lib_mes_sw = YES;
#ifdef	TMENU
/*
		sprintf( YesNoMes, "\n Catlog3Lib では、%d 個のリストを処理できます。",
			max_lib
		);
		PrintMessage( YesNoMes );
*/
#endif
	};
	free( p );

	if ( ( fpi1 = fopen( file , "rb" ) ) == NULL ) {
		er_open( file, 0, "Catlog3Lib" );
	};
	sw = YES;
	while ( fread( &saveSayData, sizeof(struct SaveSayData), 1, fpi1 ) == 1 ) {
		CheckRtBbsLogSw		= saveSayData.RtBbsSw;
		strcpy( ForumName , saveSayData.ForumName );
		SayNum = saveSayData.SayNum;					/* LIB の番号 */
		long_to_date( SayDate , saveSayData.SayDate );
			/* フォーラム名の設定。 null の場合もある */
		strcpy( ForumNameLine , saveSayData.ForumNameLine );
			/* 会議室名（ＤＬのタイトル）の設定。 null の場合もある */
		strcpy( ForumNameLineSub , saveSayData.ForumNameLineSub );

		/* clear */
		for ( i = 0 ; i < max_lib ; i++ ) {
			*(CatlogLibList[i].New)= *(CatlogLibList[i].old)= '\0';
		};

		/* データを CatlogLibList[].New に入れる */
		if ( ( fpi2 = fopen( saveSayData.FileName, "r" ) ) == NULL ) {
			er_open( saveSayData.FileName, 0, "Catlog3Lib" );
		};
		fseek( fpi2, saveSayData.BStart, SEEK_SET );
		while ( ftell( fpi2 ) < saveSayData.BEnd ) {
			fgets( str , 1024, fpi2 );						// 先読み
			lineNum = atoi( str );
			if ( lineNum > 0 ) {
				without_crlf( str );
				if ( max_lib <= lineNum ) catlog_lib_over_error();
				StrCut( str, 80 );							// 1行80文字にする
				strcpy( CatlogLibList[ lineNum ].New , str );
			};
		};
		fclose( fpi2 );

		/* 登録済のデータをロードする */
		catlog_lib_load( );

		/* ファイルに書き出す */
		if ( Catlog3LibSave( ) == NO )		break;
		if ( sw == NO )						break;
	};
	fclose( fpi1 );
	free( CatlogLibList );
}

/**************************************************************************/
/**************************************************************************/
/**************************************************************************/

/*
;	-MakeUpDL-Into1File:xxxxx	; ﾃﾞｰﾀﾗｲﾌﾞﾗﾘｰを１つのファイルにまとめる
*/

static	char	*MakeUpDLInto1File_path;

static	void	MakeUpDLInto1File_loop( const char *f_name )
{
	int		lib , sw;

	/* 調査済のディレクトリは処理を行わない */
	if (	*MakeUpDLInto1File_path != '\0'
	&&		strcmp( MakeUpDLInto1File_path, catlog_findfirst_path ) == 0
	) {
		return;
	};
	strcpy( MakeUpDLInto1File_path, catlog_findfirst_path );

	/* LIB 番号順にファイルに追加する */
	sw = NO;
	for ( lib = 1 ; lib <= 20 ; lib++ ) {
		sprintf( FileName , "%sLIB%02d.txt", catlog_findfirst_path, lib );
		if ( GetFileSize( FileName ) <= 0L )						continue;
		if ( isCATLOGFile( FileName ) != LIB )						continue;
		if ( ( CatlogFpi = fopen( FileName , "r" ) ) == NULL )		continue;
		/* FORUM:xxxx LIB:dd の行 */
		fgets( str , LINE , CatlogFpi );	fprintf( CatlogFpo , "%s" , str );
		/* ＜？？？？？＞ の行 */
		fgets( str , LINE , CatlogFpi );
		if ( sw == NO )		fprintf( CatlogFpo , "%s" , str );
		fgets( str , LINE , CatlogFpi );
		if ( strncmp( str , "1:お知らせ" , 10 ) == 0 ) {
			/* ３行読み飛ばす */
			fgets( str , LINE , CatlogFpi );
			fgets( str , LINE , CatlogFpi );
			if ( sw == NO ) {
				prMesInputLine( CatlogFpo );
				sw = YES;
			};
		} else if ( strncmp( str , "＞" , 2 ) == 0 ) {	/* ＞LIB dd の行？ */
			if ( sw == NO ) {
				prMesInputLine( CatlogFpo );		sw = YES;
			};
			fprintf( CatlogFpo , "%s" , str );
		} else {
			if ( sw == NO ) {
				prMesInputLine( CatlogFpo );		sw = YES;
			};
			fprintf( CatlogFpo , "＞LIB %d\n" , lib );
			fprintf( CatlogFpo ,
				"番号  ID       登録日付 バイト  参照   データ名\n"
			);
			fprintf( CatlogFpo , "%s" , str );
		};
		while( fgets( str , LINE , CatlogFpi ) != NULL ) {
			fprintf( CatlogFpo , "%s" , str );
		};
		fprintf( CatlogFpo , "\n\n" );
		fclose( CatlogFpi );
		HatsugenSu++;
	};
}

void	MakeUpDLInto1File_main( char *file )
{
	check_and_make_output_path( file );			/* divide.c */

	if ( ( CatlogFpo = fopen( file , "w" ) ) == NULL ) {
		strcpy( FileName , file );
		error_open_file( "MakeUpDLInto1File_main" );	return;
	};

	MakeUpDLInto1File_path = (char *)malloc( 256 );
	*MakeUpDLInto1File_path = '\0';

	HatsugenSu = 0;
	if ( *DLDir != '\0' ) {
		CatlogFindFirst2(DLDir, MakeUpDLInto1File_loop);
	};
	if ( HatsugenSu == 0 ) {
		CatlogFindFirst2(OutDir, MakeUpDLInto1File_loop);
	};

	fclose( CatlogFpo );	CatlogFpo= NULL;

	free( MakeUpDLInto1File_path );
}

int		CheckMainLoop( const char *inDir )
{
	const	char	*p1;
	char	inDirSub[ MAX_DIRS ], *p2;
	FILE	*fpi;
	int		reStoreLZHSw ;

	p1= inDir;
	while ( *p1 != '\0' ) {
		p2= inDirSub;
		while( *p1 != '\0' ) {
			if ( *p1 == ',' || *p1 == ';' ) {	p1++;	break;	};
			*p2++ = *p1++;
		};
		*p2= '\0';
		// 末尾の￥を削除しておく
		p2--;
		if ( *p2 == '\\' )	*p2 = '\0';
		if ( ( fpi= fopen( inDirSub, "r" ) ) != NULL ) {
			fclose( fpi );
			// 拡張子が LZH の場合は解凍を指示する
			// LZH	ReStoreLZHSw == YES
			reStoreLZHSw = ReStoreLZHSw ;
			p2= last_yen( inDirSub );
			if (	p2 != inDirSub
			&&		p2 != last_comma( p2 )
			) {
				p2= last_comma( p2 );
				if ( matchstr2( ".LZH", p2 ) == YES )	ReStoreLZHSw = YES;
			};
			Check1File( inDirSub, last_yen( inDirSub ) + 1 );
			ReStoreLZHSw = reStoreLZHSw ;
		} else {
			CatlogFindFirst( inDirSub, Check1File );
		};
		if ( CheckAbortSw == YES )	break;
	};
	return( YES );
}

// １つの会議室の整理を行う
static	void	CheckMainCatlogMain1Kaigi( const char *file )
{
	int		d;
	FILE	*fpi;
	char	sub1[ 128 ] , sub2[ 128 ] ;

	CheckAbort();
	if ( CheckAbortSw == YES )										return;

	if ( GetFileSize( file ) < sizeof( struct SaveSayData ) )		return;

	/*************************************************/
	/* TMPファイルからフォーラム名と会議室番号を得る */
	/*************************************************/
	if ( ( fpi = fopen( file , "rb" ) ) == NULL ) {
		er_open( file, 0, "CheckMainCatlogMain1Kaigi" );
	};
		// ファイルから読み込む
		fread( &saveSayData, sizeof(struct SaveSayData), 1, fpi );
		CheckRtBbsLogSw		= saveSayData.RtBbsSw;
		strcpy( ForumName ,   saveSayData.ForumName );
		MesNum				= saveSayData.MesNum;
		strcpy( ForumNameLine, saveSayData.ForumNameLine );
		strcpy( ForumNameLineSub, saveSayData.ForumNameLineSub );
		/* SayId は catlog_collect_lib で必要 */
		Long2Id( SayId , saveSayData.SayId );
	fclose( fpi );

	if (	MesNum == COLLECT_ID
	||		MesNum == COLLECT_LIB
	) {
		strcpy( ForumName , SayId );
	};

	// TopMenu と ForumNameData にセットする
	CheckAndSetForumNameData( ForumName, MesNum );

	mess_check
	{							/* ﾒｯｾｰｼﾞ表示のｽｲｯﾁ */
		strcpy( sub2 , "<" );
		strcat( sub2 , ForumName );	strcat( sub2 , ">" );
#ifdef	TMENU
		to_shift_zen_s( sub2, sub1 );
#else
		strcpy( sub1, sub2 );
#endif
		d = ( 20 - strlen( sub1 ) ) / 2;	if ( d < 0 ) d = 0;
		strcpy( str , "                  " );		*( str + d ) = '\0';
		strcat( str , sub1 );
		strcat( str , "                  " );		*( str + 20 ) = '\0';
		switch( MesNum ) {
			case HP:			strcat( str , "の Home Party " );	break;
			case PATIO:			strcat( str , "の ＰＡＴＩＯ " );	break;
			case MAIL:
			case ALL_MAIL:
								strcat( str , "からの　メール" );
								break;
			case BILL:		strcpy( str , 
							"ＢＩＬＬ情報です………………………" );	break;
			case COLLECT_ID:	strcat( str , "の　発言の収集" );	break;
			case LIB:			strcat( str , "のＤＬのリスト" );	break;
			case COLLECT_LIB:	strcat( str , "のDLリスト収集" );	break;
			case CLIP:
				strcpy(str,"　　　クリッピングサービス　　　　");	break;
			default:			strcat( str , "の" );
								sprintf( sub2 , "%2d" , MesNum );
#ifdef	TMENU
								to_shift_zen_s( sub2, sub1 );
#else
								strcpy( sub1, sub2 );
#endif
								strcat( str , sub1 );
								strcat(	str , "番会議室" );			break;
		};
#ifdef	TMENU
		sprintf( YesNoMes, "\n%s → ", str );
		PrintMessage( YesNoMes );
#endif
	};

	HatsugenSu = 0;
	switch( MesNum ) {
		case LIB:
//			free( catlog );
			Catlog3Lib( file );
//			catlog_malloc();
			break;
		case COLLECT_LIB:	catlog_collect_lib( file );			break;
		case CLIP:			catlog_clip_main( file );			break;
		default:			catlog_loop_sub( file );			break;
	};

#ifdef	TMENU
	mess_check {
		sprintf( YesNoMes, "%4d 個を登録。",HatsugenSu);
		PrintMessage( YesNoMes );
	};
#endif

	/*******************/
	/* delete tmp file */
	/*******************/
	remove( file );
}

static	void	CheckMainCatlogMainForum( const char *file )
{
	int		i;
	char	fileName[ MAX_FILENAME_LEN ], *fileNameP;
	FILE	*fpi;

	CheckAbort();
	if ( CheckAbortSw == YES )							return;

	strcpy( fileName, file );
	fileNameP= last_comma( fileName ) + 3;				// 最後の１文字
	for ( i= 0; i < 20 ; i++ ) {
		*fileNameP		= 'A' + i ;
		if ( ( fpi= fopen( fileName, "r" ) ) != NULL ) {
			fclose( fpi );
			// fileName が TmpFile
			CheckMainCatlogMain1Kaigi( fileName );
		};
		if ( CheckAbortSw == YES )	break;
	};
	fileNameP--;										// 最後から２番目
	for ( ; i< MAX_KAIGISHITSU ; i++ ) {
		*fileNameP		= 'A' + i / 26 ;
		*(fileNameP+1)	= 'A' + i % 26 ;
		if ( ( fpi= fopen( fileName, "r" ) ) != NULL ) {
			fclose( fpi );
			// fileName が TmpFile
			CheckMainCatlogMain1Kaigi( fileName );
		};
		if ( CheckAbortSw == YES )	break;
	};
}

static	void	RemoveLzhDir( const char *path )
{
			int		done;
#ifdef	TMENU
			VECTOR		DTA;
			FMDTA		ffblk;
#else	// TMENU
	struct	_find_t		ffblk;
#endif
			char	f_name[ MAX_FILENAME_LEN ];

	if ( CheckAbortSw == YES )									return;

	strcpy( f_name , path );		append_yen( f_name );
	strcat( f_name , "*.*" );								// 全ファイルを検索
#ifdef	TMENU
	FM_SetDta( &ffblk );
#endif	// TMENU
	done= FirstFile( f_name, FA_DIREC );
	while( ! done ) {
		CheckAbort();
		if ( CheckAbortSw == YES )									break;
		strcpy( f_name , path );	append_yen( f_name );
		strcat( f_name , ffblk.name );
		if ( ( ATTR & FA_DIREC ) == FA_DIREC ) {
			if (	strcmp( ffblk.name , "." ) != 0
			&&		strcmp( ffblk.name , ".." ) != 0
			) {
#ifdef	TMENU
				FM_SaveDta( &DTA );
#endif	// TMENU
				RemoveLzhDir( f_name );
#ifdef	TMENU
				FM_RecovDta( &DTA );
#endif	// TMENU
				if ( CheckAbortSw == YES )							break;
				rmdir( f_name );
			};
		} else {
			/* ファイル名 */
			remove( f_name );
		};
		done = NextFile;
	};
}

void	CheckMainCatlogMain()
{
			int			done;
#ifdef	TMENU
			VECTOR		DTA;
			FMDTA		ffblk;
#else	// TMENU
	struct	_find_t		ffblk;
#endif
			char		fileName[ MAX_FILENAME_LEN ], *fileNameP;
	struct	SrchFile	*srch;
			char		*srchE;
			FILE		*fpi;

	CheckAbort();
	if ( CheckAbortSw == YES )								return;

	if ( AllHatsugenSu == 0 ) {
#ifdef	TMENU
		mess_check	PrintMessage( "\n発言を見つけられませんでした。");
#endif
	} else {
#ifdef	TMENU
		mess_check {
			sprintf( YesNoMes, "\n全部で %d 個の発言がありました。",
				AllHatsugenSu
			);
			PrintMessage( YesNoMes );
		};
#endif
		if ( CheckMainCatlogMainSw == NO )						return;

		catlog_malloc();

		// TmpDir から発言データ・ファイルを読み込む
		SetTmpDir( fileName );
		// fileNameP : Dir
		fileNameP= fileName;	while( *fileNameP )	fileNameP++;
		for ( srch= SrchFile; srch->fileName != NULL ; srch++ ) {
			CheckAbort();
			if ( CheckAbortSw == YES )	break;
			if ( *(srch->sw) == YES ) {
				*fileNameP= '\0';	strcat( fileNameP, srch->fileName );
#ifdef	TMENU
				FM_SetDta( &ffblk );
#endif
				done= FirstFile( fileName, 0 );	// ファイルを選択
				while ( ! done ) {
#ifdef	TMENU
					FM_SaveDta( &DTA );
#endif
					if ( ( ATTR & 0x1f ) == 0 ) {
						*fileNameP= '\0';	strcat( fileNameP , ffblk.name );
						// fileName が見つけたファイル名
						srchE= srch->fileName;
						while( *srchE )	srchE++;	srchE--;
						if ( *srchE == '?' ) {
							// フォーラムの会議室の場合
							CheckMainCatlogMainForum( fileName );
						} else {
							// fileName が TmpFile
							CheckMainCatlogMain1Kaigi( fileName );
						};
					};
#ifdef	TMENU
					FM_RecovDta( &DTA );
#endif	// TMENU
					if ( CheckAbortSw == YES )		break;
					done = NextFile;
				};
			};
		};

		for ( srch= SrchFile; srch->fileName != NULL ; srch++ ) {
			*(srch->sw) = NO;
		};

		/* 確保した領域を解放する */
		if ( catlog != NULL ) {
			free( catlog );			catlog= NULL;			max_catlog= 0;
		};
		FileCopyEnd();
	};

	CheckAbort();
	if ( CheckAbortSw == YES )							return;

	// 1993.12.11 追加		最後に「会議室」「ＤＬ」ファイルを作る
	// 1995.5.23 削除
//	catlog_save_kaigi();
//	catlog_save_DL();
	/* 1994.2.3 新関数 */
	catlog_save_ID_TXT();

	// 「強制的に削除するファイル」を削除する
	SetTmpDirFile( FileName, FORCE_DEL_FILE_TABLE_FILE_NAME );
	if ( ( fpi= fopen( FileName, "r" ) ) != NULL ) {
		while( fgets( str, LINE, fpi ) != NULL ) {
			without_crlf( str );
#ifdef	TMENU
			mess_check {
				sprintf( YesNoMes, "\n<%s>を削除します。", str );
				PrintMessage( YesNoMes );
			};
#endif
			CheckAbort();
			if ( CheckAbortSw == YES )					return;
			remove( str );
		};
		fclose( fpi );
		remove( FileName );
	};
	// 「削除するファイル」を削除する
	SetTmpDirFile( FileName, DEL_FILE_TABLE_FILE_NAME );
	if ( ( fpi= fopen( FileName, "r" ) ) != NULL ) {
		while( fgets( str, LINE, fpi ) != NULL ) {
			without_crlf( str );
			sprintf( YesNoMes, "\n<%s>を削除します", str );
			if ( get_yesno( YesNoMes ) == YES ) {
				remove( str );
			};
		};
		fclose( fpi );
		remove( FileName );
	};

	// TmpDir の下のファイルを全部削除する
#ifdef	TMENU
	mess_check	PrintMessage( "\nＴＭＰファイルを削除します" );
#endif
	SetTmpDir( FileName );
	RemoveLzhDir( FileName );
}

static	struct	SetWithoutSearchMesType	SetWithoutSearchMesType[] = {
	{	&WithoutHPSaySw,	"HP"		},
	{	&WithoutMESSaySw,	"MES"		},
	{	&WithoutMAILSaySw,	"MAIL"		},
	{	&WithoutLIBSaySw,	"LIB"		},
	{	&WithoutBILLSaySw,	"BILL"		},
	{	&WithoutPATIOSaySw,	"PATIO"		},
	{	&WithoutCLIPSaySw,	"CLIP"		},
	{	NULL,				NULL		}
};
static	void	CheckMainSetWithoutSearchMesType()
{
			char	*src,*trg;
	struct	SetWithoutSearchMesType	*p;

	// 初期化
	for ( p= SetWithoutSearchMesType ; p->mes != NULL; p++ )	*(p->sw)= NO;

	src= WithoutSearchMesType;
	while( *src ) {
		trg= str;
		while( *src ) {
			if ( *src == ',' || *src == ';' ) {		src++;		break;	};
			*trg++= *src++;
		};
		*trg= '\0';
		touppers( str );		// 大文字にする
		if ( *str != '\0' ) {
			for ( p= SetWithoutSearchMesType ; p->mes != NULL; p++ ) {
				if ( strcmp( str, p->mes ) == 0 ) {
					*(p->sw)= YES;
					break;
				};
			};
		};
	};
}

/****************************************************************/
/* 全体で１つのインデックスからフォーラム毎のインデックスを作る */
/****************************************************************/
static	void	makeidx_forum_mode()
{
	char	old_forum[ 128 ] , fileName[ MAX_FILENAME_LEN ] ;
	char	indexFileName[ MAX_FILENAME_LEN ];
	FILE	*fpi , *fpo;

	if ( CheckAbortSw == YES )										return;
	strcpy( fileName , OutDir );		append_yen( fileName );
	strcat( fileName , IDX_FILE_NAME );
	if ( ( fpi = fopen( fileName , "rb" ) ) == NULL )				return;

#ifdef	TMENU
	mess_check
		PrintMessage( "\nインデックスをフォーラムごとに分割します　→　");
#endif

	*old_forum = '\0';	fpo = NULL;
	MesNum = 0;
	while( fread( &catlogIndex, sizeof(struct CatlogIndex), 1, fpi ) == 1 ) {
		if ( catlogIndex.MesNum == ALL_MAIL )	catlogIndex.MesNum = MAIL;
		if (	*old_forum == '\0'
		||		strcmp( old_forum , catlogIndex.ForumName ) != 0
		||		(	(	catlogIndex.MesNum < 0
					||	MesNum < 0
					)
					&&	MesNum != catlogIndex.MesNum
				)
		||		catlogIndex.RtBbsSw != CheckRtBbsLogSw
		) {
			CheckRtBbsLogSw = catlogIndex.RtBbsSw;
			if ( fpo != NULL )	fclose( fpo );
			strcpy( old_forum , catlogIndex.ForumName );
			strcpy( ForumName , catlogIndex.ForumName );
			MesNum = catlogIndex.MesNum;
			set_index_file_name( indexFileName, ForumName );
			if ( ( fpo = fopen( FileName , "ab" ) ) == NULL ) {
				strcpy( FileName, indexFileName );
				error_open_file( "makeidx_forum_mode" );
				error_end();
			};
		};
		fwrite( &catlogIndex, sizeof(struct CatlogIndex), 1, fpo );
	};
	fclose( fpi );	fclose( fpo );

	/* mode:1 のｲﾝﾃﾞｯｸｽを削除する */
	remove( fileName );

#ifdef	TMENU
	mess_check PrintMessage("終了しました。");
#endif
}

/************************************/
/* フォーラム毎のインデックスを探す */
/************************************/
static	void	makeidx_new_type_sub( const char *f_name, const char *name )
{
	FILE	*fpi,*fpo;
	char	fileName[ MAX_FILENAME_LEN ];

	/*******************/
	/* name のチェック */
	/*******************/
	if ( strcmp( name , IDX_FILE_NAME ) != 0 )						return;

	/* 「全体で１つ」のインデックス・ファイル？ */
	strcpy( fileName , OutDir );		append_yen( fileName );
	strcat( fileName , IDX_FILE_NAME );
	if ( strcmp( fileName , f_name ) == 0 )							return;

	/* インデックスを１つにまとめる */
	if ( (fpo=fopen( fileName , "a" ) ) == NULL ) {
		strcpy( FileName , fileName );
		error_open_file( "makeidx_new_type_loop_sub" );
	};
	if ( (fpi=fopen( f_name , "rb" ) ) == NULL ) {
		strcpy( FileName , f_name );
		error_open_file( "makeidx_new_type_loop_sub" );
	};
	while( fread( &catlogIndex, sizeof(struct CatlogIndex), 1, fpi ) == 1 ) {
		fwrite( &catlogIndex, sizeof(struct CatlogIndex), 1, fpo );
	};
	fclose( fpo );	fclose( fpi );

	/************************/
	/* ファイルを消すよ〜〜 */
	/************************/
	remove( f_name );
}

/********************************************************/
/* IndexModeSw の値を調べてその値とファイルとをチェックする */
/********************************************************/
static	void	check_index_mode()
{
	if ( IndexModeSw == NO ) {
		/****************************/
		/* 全体で１つのインデックス */
		/****************************/
		strcpy( FileName , OutDir );		append_yen( FileName );
		strcat( FileName , IDX_FILE_NAME );
		if ( GetFileSize( FileName ) <= 0L ) {
#ifdef	TMENU
			mess_check {
				PrintMessage( "\nインデックスを１つにまとめます　→　");
			};
#endif
			/**************************************************************/
			/* IDX がないので、新しく作る の メイン・ルーチン             */
			// 出力ﾃﾞｨﾚｸﾄﾘの下のﾃﾞｨﾚｸﾄﾘの中の旧Typeのｲﾝﾃﾞｯｸｽ･ファイルから作る
			/**************************************************************/
			CatlogFindFirst( OutDir, makeidx_new_type_sub );
#ifdef	TMENU
			mess_check PrintMessage("終了しました。");
#endif
		};
	} else {
		/********************************/
		/* フォーラムごとのインデックス */
		/********************************/
		makeidx_forum_mode();
	};
}

void	CheckMainLoopEnd();		// ..\common_c.c

static	int		checkMainSub( const char *inDir )
{
	struct	SrchFile	*srch;

	CheckAbortSw= NO;
	AllHatsugenSu = CollectFileNumber = 0;
	CollectFileSize = 0L;
	for( srch=SrchFile; srch->fileName != NULL ; srch++)	*(srch->sw) = NO;

	/**************************************************/
	/* もしかして、以前に領域を確保していたら解放する */
	/**************************************************/
	if ( catlog != NULL ) {
		free( catlog );			catlog= NULL;			max_catlog= 0;
	};
#ifdef		DO_ON_MEMORY					// メモリ上で処理を行う
	if ( Idx != NULL ) {
		free( Idx );			Idx= NULL;				MaxIdx= 0;
	};
#endif

	if ( *OutDir == '\0' ) {
		get_yesno( "\n出力ディレクトリを指定してから始めて下さい。\nメニューに戻ります" );
		return( 0 );
	};
	if ( *inDir == '\0' ) {
		get_yesno( "\nファイル or ディレクトリを指定してから始めて下さい。\nメニューに戻ります" );
		return( 0 );
	};

	// インデックス・モード変更の処理
	check_index_mode();

	// ここで、メールを１つに纏める

	CheckAbort();
	if ( CheckAbortSw == YES )							return( 0 );

	CheckMainSetWithoutSearchMesType();

	// TmpDir の下のファイルを全部削除する
#ifdef	TMENU
	mess_check	PrintMessage( "\nＴＭＰファイルを削除します" );
#endif
	SetTmpDir( FileName );
	RemoveLzhDir( FileName );

	//	CheckAbort();
	if ( CheckAbortSw == YES )							return( 0 );

	/* 内部処理用の領域を確保する */
	SetToday( );
	max_catlog = 0;
	HatsugenSu = 0;

#ifdef		DO_ON_MEMORY					// メモリ上で処理を行う
	MaxIdx= mallocIdxSub(
#ifdef	TMENU
			10000L,
#else
			64L * 1024L / (long)sizeof( struct SayData ),
#endif
			(long)sizeof(struct SayData ),
			(char **)(&Idx)
		);
#endif

	// 「削除するファイル」の一覧ファイルの削除
	SetTmpDirFile( FileName, DEL_FILE_TABLE_FILE_NAME );
	check_and_make_output_path( FileName );
	remove( FileName );
	SetTmpDirFile( FileName, FORCE_DEL_FILE_TABLE_FILE_NAME );
	remove( FileName );


	/******************/
	/* 第１段階の実行 */
	/******************/
	if ( CheckAbortSw != YES ) {
		CheckMainLoop( inDir );
		// CheckMainLoop の事後処理
		CheckMainLoopEnd( );
	};

#ifndef	TMENU	// Win 版
	sprintf( YesNoMes, "\n checkMainSub( %s ) です 第３段階実行します", inDir);
	PrintMessage( YesNoMes );
#endif

	/******************/
	/* 第３段階の実行 */
	/******************/
	if ( CheckAbortSw != YES ) {
		CheckMainCatlogMain();
		/* 確保した領域を解放する */
		if ( catlog != NULL ) {
			free( catlog );			catlog= NULL;			max_catlog= 0;
		};
	};

#ifdef		DO_ON_MEMORY					// メモリ上で処理を行う
	// もしかして、領域を確保していたら解放する。
	if ( Idx != NULL ) {
		free( Idx );			Idx= NULL;				MaxIdx= 0;
	};
#endif

	return( AllHatsugenSu );
}

int		CheckMain( const char *inDir )
{
	int		sw;

	// インデックスの変更？
	if ( ChangeCatlog1to2Index < IndexVersion ) {
		CheckAndMakeCatlog2Index( NO );
		ForceWriteCatlogDefFileSw = YES;
	};

#ifndef	TMENU		// Windows版の場合
	if ( ReStoreLZHSw == YES ) {
		// LHA を起動できない旨を表示する
		ReStoreLZHSw = NO;
		StoreLZHSw = NO;
		// 今日より古いファイルは削除できない旨を表示する
		DeleteOldFileSw = NO;
	};
#endif

#ifdef	CATLOG_EXG		// EXG 版の場合
	if (	ReStoreLZHSw == YES
	||		StoreLZHSw == YES
	||		DeleteOldFileSw == YES
	) {
		// LHA を起動できない旨を表示する
		PrintMessage(
"\n"
"ＥＸＧ版ではＬＨＡを起動できませんので、以下のスイッチがＯＦＦになります。\n"
"\tLZH ﾌｧｲﾙからも発言を検索する\n"
"\t生ﾛｸﾞ･ﾌｧｲﾙをLZHファイルに保存する\n"
"\t今日より古い生ﾛｸﾞ･ﾌｧｲﾙを削除する\n"
		);
		ReStoreLZHSw = NO;
		StoreLZHSw = NO;
		DeleteOldFileSw = NO;
	};
#endif

	CheckMainCatlogMainSw = YES;
	sw = checkMainSub( inDir );

	if ( ForceWriteCatlogDefFileSw == YES )  {
		ForceWriteCatlogDefFileSw = NO;
		// 1995.3.5 ここで書き出しても良いのか？
//		if ( get_yesno( "DEF ファイルを書き出します" ) == YES ) {
//			WriteCatlogDef( CatlogDefFileName );
//		};
		WriteCatlogDef( CatlogDefFileName );
	};

	return( sw );
}

//	###########################################################################
//	##### SearchIdNameMain ####################################################
//	###########################################################################
static	struct	ID_NAME	*search_id_name;
static	int		max_search_id_name;

static	int		search_id_name_cmp1( const void *p11 , const void *p21 )
{
	const struct ID_NAME *p1 = (const struct ID_NAME *)p11;
	const struct ID_NAME *p2 = (const struct ID_NAME *)p21;

#ifdef	TMENU
	return( p1->id - p2->id );
#else
	if ( p1->id < p2->id )			return( -1 );
	if ( p1->id > p2->id )			return(  1 );
	return( 0 );
#endif
}

static	int		search_id_name_cmp2( const void *p11 , const void *p21 )
{
	const struct ID_NAME *p1 = (const struct ID_NAME *)p11;
	const struct ID_NAME *p2 = (const struct ID_NAME *)p21;

	return( p2->num - p1->num );
}

static	int		search_id_name_sub( long id , char *name )
{
	int		i;
	char	*p1 , *p2;

	// 登録しない場合
	if (	id == 0L
	||		*name == '\0'
	)													return( YES );

	search_id_name[ save_end ].id = id;
	p1 = search_id_name[ save_end ].name;		p2 = name;
	for ( i=0 ; i<8*2 ; i++ ) *p1++ = *p2++;	/* 漢字で８文字 */
	*p1 = '\0';

	for ( i=0 ; i<save_end ; i++ ) {
		if ( search_id_name[i].id  == id
		&&	 strcmp(search_id_name[i].name,search_id_name[save_end].name) == 0
		) {
			search_id_name[ i ].num++;		/* 出てきた回数 */
			return( YES );
		};
	};
	/* 初めて出て来た */
	search_id_name[ save_end ].num = 1;
	if ( save_end < max_search_id_name - 1 ) {
		save_end++;
/*
		if ( ( save_end & 0x01ff ) == 0 ) {
			// 発言回数でソート
			qsort(	search_id_name,
					save_end,
					sizeof(struct ID_NAME),
					search_id_name_cmp2
			);
		};
*/
		return( YES );
	};
	return( NO );
}

static
void	SearchIdNameLoop( const char *f_name, const char *name )
{
	FILE	*fp;

	if ( save_end >= max_search_id_name )					return;
	save_start = save_end;

	// インデックス・ファイルからＩＤとハンドルの値を得る
	if ( strcmp( name, IDX_FILE_NAME ) != 0 )				return;
#ifdef	TMENU
		sprintf( YesNoMes, "\n<%-40s> →",f_name);
		PrintMessage( YesNoMes );
#endif
	if ( ( fp= fopen( f_name, "rb" ) ) == NULL )			return;
	HatsugenSu= 0;
	while( fread( &catlogIndex, sizeof(struct CatlogIndex), 1, fp ) == 1 ) {
		if (	catlogIndex.MesNum == MAIL
		||		catlogIndex.MesNum == HP
		||		catlogIndex.MesNum == PATIO
		||		(	1 <= catlogIndex.MesNum
				&&	catlogIndex.MesNum <= MAX_KAIGISHITSU
				)
		) {
			HatsugenSu++;
			if ( catlogIndex.MesNum == HP ) {
				if (search_id_name_sub(catlogIndex.SayId, "HP-Say" ) != YES ) {
					break;
				};
			} else {
				if (search_id_name_sub(catlogIndex.SayId,catlogIndex.Handle)!=YES){
					break;
				};
			};
		};
	};
	AllHatsugenSu += HatsugenSu;
	fclose( fp );
#ifdef	TMENU
	sprintf( YesNoMes, " 発言:%4d 全発言:%5d 追加:%4d 個 合計:%4d",
		HatsugenSu,
		AllHatsugenSu,
		save_end - save_start,
		save_end
	);
	PrintMessage( YesNoMes );
#endif
}

/**************************************/
/* ＩＤとハンドルの対応ファイルを作る */
/**************************************/
#define	ID_HANDLE_FORMAT	"%8s → %16s %4d 回\n"
void	SearchIdNameMain( const char *out_file )
{
	int		i, id, sw;
	char	*p;

#ifdef	TMENU
//	mess_check	PrintMessage( "\nＩＤ−ハンドル表を作ります" );
#endif

	/* 初期化 */
	max_search_id_name= mallocIdxSub(
#ifdef	TMENU
			10001L,
#else
			64L * 1024L / (long)sizeof( struct ID_NAME ),
#endif
			(long)sizeof(struct ID_NAME ),
			(char **)(&search_id_name)
		);
#ifdef	TMENU
	mess_check {
		sprintf( YesNoMes, "\n %d 個までのＩＤを処理できます",
			max_search_id_name
		);
		PrintMessage( YesNoMes );
	};
#endif

	save_start = save_end = 0;

	/* 1994.2.12 追加 out_file から ID-Handle 表を読み込む */
	if ( ( CatlogFpi = fopen( out_file , "r" ) ) != NULL ) {
#ifdef	TMENU
		mess_check {
			sprintf( YesNoMes, "\n<%s>から対応表を読み込みます → ", out_file);
			PrintMessage( YesNoMes );
		};
#endif
		while ( fgets( str, LINE, CatlogFpi ) != NULL ) {
			if ( strncmp( str, "-----", 5 ) == 0 )	break;
			str[8]= '\0';
			if ( isIDname( str ) != YES )			continue;
			p= skip_space( str + 9 );
			if ( strncmp( p, "→", 2 ) == 0 )		p= skip_space( p + 2 );
			if ( *p == '\0' )						continue;
			search_id_name[ save_end ].id = Id2Long( str );
			strncpy( search_id_name[ save_end ].name, p, 16 );
			search_id_name[ save_end ].name[16] = '\0';
			search_id_name[ save_end ].num = 0;
			if ( save_end < max_search_id_name -1 )		save_end++;
		};
		fclose( CatlogFpi);
#ifdef	TMENU
		mess_check {
			sprintf( YesNoMes, "%d 個のデータがありました", save_end );
			PrintMessage( YesNoMes );
		};
#endif
	};

	/* 整理済みのファイルを検索 */
	sw= Display;
	Display= NO ;
	AllHatsugenSu = 0;
	CatlogFindFirst( OutDir, SearchIdNameLoop );
	Display= sw;

	/* IDでソート */
	qsort(search_id_name,save_end,sizeof(struct ID_NAME),search_id_name_cmp1);

	/* ファイルに書き出す */
	if ( ( CatlogFpo = fopen( out_file , "w" ) ) == NULL ) {
		strcpy( FileName , out_file );
		error_open_file( "ＩＤ・ハンドル対応表の書き込み" );		return;
	};
	for ( i=0 ; i<save_end ; i++ ) {
		Long2Id( str, search_id_name[ i ].id );
		fprintf( CatlogFpo ,ID_HANDLE_FORMAT,
			str,
			search_id_name[ i ].name,
			search_id_name[ i ].num
		);
	};
	/* 発言回数でソート */
	qsort(search_id_name,save_end,sizeof(struct ID_NAME),search_id_name_cmp2);
	fprintf( CatlogFpo , "------------------------------------------\n" );
	for ( i=0 ; i<save_end ; i++ ) {
		id = search_id_name[ i ].id;
		if ( id != 0L ) {
			Long2Id( str, id );
			for ( sw= i; sw<save_end; sw++ ) {
				if ( id == search_id_name[ sw ].id ) {
					fprintf( CatlogFpo ,ID_HANDLE_FORMAT,
						str,
						search_id_name[ sw ].name,
						search_id_name[ sw ].num
					);
					search_id_name[ sw ].id = 0L;
				};
			};
		};
	};
	fclose( CatlogFpo );	CatlogFpo= NULL;
	free( search_id_name );		/* 使った領域を開放する */

#ifdef	TMENU
//	mess_check	PrintMessage( "\nＩＤ−ハンドル表 作成を終了しました" );
#endif
}

//	###########################################################################
//	##### SearchIdSayMain #####################################################
//	###########################################################################
// Collect_ID によって発言を収集する
void	SearchIdSayMain( const char *path )
{
	if ( *SearchID == '\0' ) {
		PrintMessage("検索するＩＤが設定されていません。メニューに戻ります。");
		return;
	};
	SearchIdSayMainSw= YES;
	CheckMain( path );
	SearchIdSayMainSw= NO;
}

//	###########################################################################
//	##### SetOptions ##########################################################
//	###########################################################################
int		SetOptions( const char *option )
{
			int		i, pLen ;
	const	char	*p1;
			char	*p;

	if ( matchstr( option, "ForumName:" ) == YES ) {
		p = (char *)(option + 10);
		if ( YamaBbsAccessOkSw == YES ) {
			CheckAndSetForumNameData( "Yama-BBS", 1 );
		};
		CheckAndSetForumNameData( p, 1 );
		return( YES );
	};

	if ( matchstr( option, "RT-BBS:" ) == YES ) {
		SetRtBbsListMenu( (char *)(option+7) );
		return( YES );
	};

	for ( i=0; InsideVar[i].Mes != NULL; i++ ) {
		p1= InsideVar[i].Option;	pLen= strlen( p1 );
		if ( strncmp( option, p1, pLen ) == 0 ) {
			strcpy( InsideVar[i].insideVar, option + pLen );
			return( YES );
		};
	};
	for ( i=0; InsideBoolSw[i].Mes != NULL; i++ ) {
		p1= InsideBoolSw[i].Option;	pLen= strlen( p1 );
		if ( strncmp( option, p1, pLen ) == 0 ) {
			if ( strncmp( option + pLen, "TRUE", 4 ) == 0 ) {
				*InsideBoolSw[i].insideVar= YES;
#ifdef	TMENU
				if ( matchstr( p1, RT_BBS_ACCESS_OK_SW_MES ) == YES ) {
					// TopMenu の選択を許可する
					AccessYamaBbsOk( YES );				// yamabbs.c
				};
#endif
			} else if ( strncmp( option + pLen, "FALSE", 4 ) == 0 ) {
				*InsideBoolSw[i].insideVar= NO;
			} else {
				*InsideBoolSw[i].insideVar= NO;			// スイッチが未設定
			};
			return ( YES );
		};
	};
	for ( i=0; InsideIntData[i].Mes != NULL; i++ ) {
		p1= InsideIntData[i].Option;	pLen= strlen( p1 );
		if ( strncmp( option, p1, pLen ) == 0 ) {
			*InsideIntData[i].insideVar= atoi( option + pLen );
			return( YES );
		};
	};
	return( NO );
}

//	###########################################################################
//	##### SetTmpDir ###########################################################
//	###########################################################################
void	SetInsideTmpDir()
{
	char	*p;

	if ( *TmpDir == '\0' ) {
		// MS-DOS の環境変数から TmpDir を設定する
		p= getenv( "TEMP" );
		if ( *p != '\0' && p != NULL )		strcpy( TmpDir, p );
		p= getenv( "TMP" );
		if ( *p != '\0' && p != NULL )		strcpy( TmpDir, p );
		// TmpDir が '\0' の場合はｶﾚﾝﾄ･ﾄﾞﾗｲﾌﾞのﾙｰﾄに TmpDir を設定する
		if ( *TmpDir == '\0' ) {
#ifdef	TMENU
			sprintf( TmpDir, "%c:\\TMP\\",FM_GetCurrentDisk() );
//			check_and_make_output_path( TmpDir );
#endif
		};
	};
	// ドライブ名のみの場合はルートディレクトリにする
	p= TmpDir;	while( *p )		p++;
	if ( *(p-1) == ':' ) {
		*p++ = '\\';
		*p= '\0';
	};
	check_and_make_output_path( TmpDir );
}


//	###########################################################################
//	##### CheckAndMakeCatlog2Index ############################################
//	###########################################################################
//	インデックスの変更
static	void	MakeCatlog2IndexSubDel( const char *f_name, const char *name )
{
	// CATLOG1 のインデックス・ファイル？
	if (	strcmp( name, "CATLOG.IDX" ) != 0
	&&		strcmp( name, IDX_FILE_NAME ) != 0
	)														return;
	// 削除！
	remove( f_name );
}

// 発言データ・ファイルからインデックスを作る
static	void	MakeCatlog2IndexSub2( const char *f_name, const char *name )
{
	FILE	*fpi, *fpo;
	char	fileName[ MAX_FILENAME_LEN ];

	/***********************************************/
	/* file から登録済みの発言のデータをメモリーへ */
	/***********************************************/
	if ( ( fpi = fopen( f_name , "rb" ) ) == NULL ) {
		er_open( f_name, 0, "MakeCatlog2IndexSub2" );
	};
	if ( fread(&saveSayData,sizeof(struct SaveSayData),1,fpi ) != 1 ) {
		fclose( fpi );
		return;
	};
	CheckRtBbsLogSw		= saveSayData.RtBbsSw;
	strcpy( ForumName,    saveSayData.ForumName );
	MesNum				= saveSayData.MesNum;

	CheckAndSetForumNameData( ForumName, MesNum );

	fseek( fpi, 0, SEEK_SET );
	set_index_file_name( fileName, ForumName );
	if ( ( fpo = fopen( fileName , "ab+" ) ) == NULL ) {
		er_open( fileName, 1, "MakeCatlog2IndexSub2" );
	};
	while( fread(&saveSayData,sizeof(struct SaveSayData),1,fpi ) == 1 ) {
		// 発言データをインデックスデータに変更する
		catlogIndex.RtBbsSw	= saveSayData.RtBbsSw;			// RT-BBSの発言
		catlogIndex.MesNum	= saveSayData.MesNum;			// 会議室番号
		catlogIndex.SayNum	= saveSayData.SayNum;			// 発言番号
		catlogIndex.ComNum	= saveSayData.ComNum;			// コメント元番号
		catlogIndex.SayDate	= saveSayData.SayDate;			// 発言日時
		catlogIndex.seek		= saveSayData.BStart;		// Seek位置
		catlogIndex.SaySize	= saveSayData.BEnd - saveSayData.BStart;
		catlogIndex.SayLine	= saveSayData.GEnd - saveSayData.GStart;
															// 発言の大きさ
		catlogIndex.SayId		= saveSayData.SayId;		// 発言者ID→数値化
		strcpy( catlogIndex.ForumName, saveSayData.ForumName );	// フォーラム名
		strcpy( catlogIndex.Handle, saveSayData.Handle );	// 発言者のハンドル
		strcpy( catlogIndex.Mes, saveSayData.Mes );			// 発言の標題
		// 書き出したファイル番号
		catlogIndex.FileNum = GetCatlogFileNum( saveSayData.FileName );
		// 既読スイッチの設定
		catlogIndex.kidoku= ' ';
//		PrintMessage( "\n次のデータを登録します" );
//		PrintIndexData( catlogIndex );
		fwrite( &catlogIndex, sizeof(struct CatlogIndex), 1, fpo );
	};
	fclose( fpi );	fclose( fpo );
	// 削除！
	remove( f_name );
}

static	void	MakeCatlog2IndexSub( const char *f_name, const char *name )
{
	// 整理済ファイル？
	if ( isCATLOGFile( f_name ) == 0 )						return;

	// LIB の場合 何もしない
	if ( MesNum == LIB )									return;

	Check1File( f_name, name );
}

void	CheckAndMakeCatlog2Index( int firstRunSw )
{
	char	*p;
	int		sw;
	char	fileName[ MAX_FILENAME_LEN ];

	// 内部スイッチのチェック
	if ( ChangeCatlog1to2Index >= IndexVersion )			return;

	if ( *IndexDir != '\0' ) {		p= IndexDir;
	} else {						p= OutDir;
	};
	if ( *p == '\0' )										return;

#ifdef	TMENU
	if ( firstRunSw == YES ) {
		sprintf( YesNoMes, "\nようこそ、ＣＡＴＬＯＧ %s へ！！ ", VERSION );
		PrintMessage( YesNoMes );
	} else {
		PrintMessage( "\nインデックス・ファイルのバージョンが古いようです。" );
	};
	PrintMessage( "インデックスを作り直すので、しばらくお待ち下さい。" );
#endif

#ifdef	TMENU
	PrintMessage( "\n　　まず、ＴＭＰファイルを削除します" );
#endif
	SetTmpDir( fileName );
	RemoveLzhDir( fileName );

#ifdef	TMENU
	PrintMessage( "\n　　次に、インデックスを削除します。" );
#endif
	sw= Display;
	Display= NO ;
	CatlogFindFirst( p, MakeCatlog2IndexSubDel );

#ifdef	TMENU
	PrintMessage( "\n　　次に、整理済のファイルからインデックスを作ります。" );
#endif

	CheckAndMakeCatlog2IndexSw = YES;
	CatlogFindFirst( OutDir, MakeCatlog2IndexSub );
	CheckAndMakeCatlog2IndexSw = NO;

	SetTmpDir( fileName );
	CatlogFindFirst( fileName, MakeCatlog2IndexSub2 );

	Display= sw;
	ChangeCatlog1to2Index = IndexVersion ;
#ifdef	TMENU
	PrintMessage( "\nインデックスの作り直しを終了しました。\n" );
#endif
}

//	###########################################################################
//	##### ReadCatlogDef #######################################################
//	###########################################################################
//	DefFileName から初期情報を得る
int		ReadCatlogDef( const char *DefFileName )
{
	int		sw;
	FILE	*fpi;

	SetToday();
	if ( ( fpi = fopen( DefFileName, "r" )) == NULL ) {
		//	オープンエラー
		return( NO );
	};
	sw= NO;
	InitialInsideVars();
	CheckAndSetForumNameData( NULL, 0 );
#ifdef	TMENU
	// TopMenu の選択を不許可にする
	AccessYamaBbsOk( NO );				// yamabbs.c
#endif
	while( fgets( str, LINE, fpi ) != NULL ) {
		if ( ! isalpha( *str ) )		continue;
		without_crlf( str );
		if ( SetOptions( str ) == YES )		sw= YES;
	};
	fclose( fpi );
	SetInsideTmpDir();

	if ( *RtBbsRootDir == '\0' ) {
		// RtBbsRootDir が空の時は起動ディレクトリを設定しておく
		strcpy( RtBbsRootDir, Catlog2ExecDir );
	} else {
		char	dirName[ MAX_FILENAME_LEN ];

		// RtBbsRootDir が空でない時はディレクトリを作成しておく
		strcpy( dirName, RtBbsRootDir );	append_yen( dirName );
		check_and_make_output_path( dirName );
	};


/*	1995.3.5 コメント・アウト
	CheckAndMakeCatlog2Index( NO );
*/
	ForceWriteCatlogDefFileSw = NO;
	return( sw );
}

//	###########################################################################
//	##### WriteCatlogDef ######################################################
//	###########################################################################
//	内部に保存している情報を DefFileName に書き出す
static	char	*DefMes[] =		{
	"このファイルはＣＡＴＬＯＧ２の定義ファイルです。",
	"各行の１文字目が空白の場合はコメントとして無視されます。",
	"",
	"スイッチは TRUE(真 Yes の意味) または FALSE(偽 No の意味) を書いて下さい。",
	"",
	"なお、「内部データ」とある指定は削除や変更をしないようにして下さい。",
	"また、「(*)」の印の付いている所は、必ず指定するようにして下さい。",
	"",
	NULL
};

int		WriteCatlogDef( const char *DefFileName )
{
	int		i;
	FILE	*fpo;

	if ( ( fpo = fopen( DefFileName, "w" )) == NULL ) {
		//	オープンエラー
		return( NO );
	};
	for ( i=0; DefMes[i] != NULL ; i++ ) {
		fprintf( fpo, " %s\n", DefMes[i] );
	};
	// 文字列データ
	for ( i=0; InsideVar[i].Mes != NULL; i++ ) {
		fprintf( fpo, " %s\n%s%s\n\n"
			, InsideVar[i].Mes, InsideVar[i].Option
			, InsideVar[i].insideVar
		);
	};
	// スイッチ類
	for ( i=0; InsideBoolSw[i].Mes != NULL; i++ ) {
		// RT_BBS_ACCESS_OK_SW_MES が NO の時は書き出さないようにする
		if ( strcmp(InsideBoolSw[i].Option,RT_BBS_ACCESS_OK_SW_MES) == 0 ) {
			if ( *InsideBoolSw[i].insideVar == YES ) {
				fprintf( fpo, " %s\n%sTRUE\n\n"
					, InsideBoolSw[i].Mes, InsideBoolSw[i].Option
				);
			};
		} else {
			if ( *InsideBoolSw[i].insideVar == YES ) {
				fprintf( fpo, " %s\n%sTRUE\n\n"
					, InsideBoolSw[i].Mes, InsideBoolSw[i].Option
				);
			} else {
				fprintf( fpo, " %s\n%sFALSE\n\n"
					, InsideBoolSw[i].Mes, InsideBoolSw[i].Option
				);
			};
		};
	};
	// 数値データ
	for ( i=0; InsideIntData[i].Mes != NULL; i++ ) {
		fprintf( fpo, " %s\n%s%d\n\n"
			, InsideIntData[i].Mes, InsideIntData[i].Option
			, *InsideIntData[i].insideVar
		);
	};

	fprintf(fpo," 以下はフォーラム名 → 内部データ（変更しないで下さい）\n");
	extern	void	WriteForumNameData( FILE *fpo );
					WriteForumNameData( fpo );
	fprintf(fpo,"\n");
	fprintf(fpo," 以下はＲＴ−ＢＢＳ名 → 内部データ（変更しないで下さい）\n");
	extern	void	SaveRtBbsName( FILE *fpo );
					SaveRtBbsName( fpo );

	fclose( fpo );
	return( YES );
}

//	###########################################################################
//	##### InitialInsideVars ###################################################
//	###########################################################################
void	InitialInsideVars()
{
	int		i;

	for ( i=0; InsideVar[i].Mes != NULL; i++ ) {
		*InsideVar[i].insideVar = '\0';
	};
	for ( i=0; InsideBoolSw[i].Mes != NULL; i++ ) {
		*InsideBoolSw[i].insideVar = NO;
	};
	for ( i=0; InsideIntData[i].Mes != NULL; i++ ) {
		*InsideIntData[i].insideVar = 0;
	};
		IndexModeSw = YES;		// YES : フォーラム毎にインデックスを作る
		NewFileSw	= YES;		// YES : x001で新ﾌｧｲﾙを作る
	/*****************/
	/* InsideIntData */
	/*****************/
		MaxCatlogFileSize = 2048;		//	検索するファイルの総サイズ
		MaxSeisyoLineSize= 70;
		Display= YES;

	SetToday();
	SetInsideTmpDir();
}

//	###########################################################################
//	##### GetVarLen ###########################################################
//	###########################################################################
int		GetVarLen( char *var )
{
	int		i;

	for ( i=0; InsideVar[i].insideVar != NULL ; i++ ) {
		if ( InsideVar[i].insideVar == var ) {
			return( InsideVar[i].len );
		};
	};
	return( 0 );
}


//	###########################################################################
//	##### GetVarMes ###########################################################
//	###########################################################################
char	*GetVarMes( char *var )
{
	int		i;

	for ( i=0; InsideVar[i].insideVar != NULL ; i++ ) {
		if ( InsideVar[i].insideVar == var ) {
			return( InsideVar[i].Mes );
		};
	};
	return( "不明の変数です" );
}


//	###########################################################################
//	##### ArrangeIndexData ### インデックスの整理 #############################
//	###########################################################################
static	void	ArrangeIndexDataSubIndex(const char *f_name, const char *name )
{
	char	*p;
	char	fileName[ MAX_FILENAME_LEN ];
	FILE	*fpi, *fpo;

	if ( strcmp( name, IDX_FILE_NAME ) != 0 )				return;

	strcpy( fileName, f_name );
	p= last_comma( fileName );	*p = '\0';	strcat( p, ".BAK" );

	if ( ( fpi = fopen( f_name,   "rb" ) ) == NULL )			return;
	if ( ( fpo = fopen( fileName, "wb" ) ) != NULL ) {
		while( fread(&catlogIndex,sizeof(struct CatlogIndex), 1, fpi ) == 1 ) {
			if ( catlogIndex.MesNum == CLIP ) {
				// そのまま書き出す
				fwrite( &catlogIndex, sizeof(struct CatlogIndex), 1, fpo );
				continue;
			};
			if ( ArrangeIndexDataOldestDate <= catlogIndex.SayDate ) {
				fwrite( &catlogIndex, sizeof(struct CatlogIndex), 1, fpo );
			};
		};
		fclose( fpo );
	};
	fclose( fpi );
	remove( f_name );

	// rename( old, New );
	if ( rename( fileName, f_name ) != 0 ) {
		sprintf( YesNoMes,
			"\n" "rename <%s>→<%s> が出来ません",
			 fileName, f_name
		);
		showKakunin( YesNoMes );
	};
}

void	ArrangeIndexData( const char *inDir )
{
	char		fileName[ MAX_FILENAME_LEN ], *fileNameP;

	ArrangeIndexDataOldestDate = date_to_long( "9912312359" );
	CheckMainCatlogMainSw = NO;
	checkMainSub( inDir );

	// 最古の発言日時は ArrangeIndexDataOldestDate である
	long_to_date( fileName, ArrangeIndexDataOldestDate );
#ifdef	TMENU
	mess_check {
		sprintf( YesNoMes, "\n\n最古の発言日時は %s です", fileName );
		PrintMessage( YesNoMes );
	};
#endif

	// インデックス・ファイルを読みながら、
	//		最古の発言日時より古いインデックス・データを削除する
	if ( *IndexDir != '\0' ) {		fileNameP= IndexDir;
	} else {						fileNameP= OutDir;
	};
	if ( *fileNameP == '\0' )										return;
	// 再帰的に IDX_FILE_NAME をさがす
	CatlogFindFirst( fileNameP, ArrangeIndexDataSubIndex );
}


//	###########################################################################
//	##### GetKaigiName ########################################################
//	###########################################################################
// 整理済ファイルから会議室の内容を表す文字列を抽出し、ファイルに書き出す。
// ファイル名: KAIGI_TMP_FILE_NAME
static	int		GetKaigiNameNum= 0;

static	void	GetKaigiNameGetHandle( const char *file )
{
	FILE	*fpi;
	char	fileName[ MAX_FILENAME_LEN ];

	// 初期値
	strcpy( Handle, ForumName );	// 発言者のハンドル

	FileNum= GetCatlogFileNum( file );
	set_index_file_name( fileName, ForumName );
	if ( ( fpi = fopen( fileName, "rb" ) ) == NULL )			return;

	// ファイルからデータを読み込む
	while( fread( &catlogIndex, sizeof(struct CatlogIndex), 1, fpi ) == 1 ) {
		if ( catlogIndex.MesNum != MesNum )						continue;
		if ( catlogIndex.RtBbsSw != CheckRtBbsLogSw )			continue;
		if ( strcmp( catlogIndex.ForumName, ForumName ) != 0 )	continue;
		if ( catlogIndex.FileNum != FileNum )					continue;
		// ハンドルをセットする
		strcpy( Handle, catlogIndex.Handle );	// 発言者のハンドル
		break;
	};
	fclose( fpi );
}

static	void	GetKaigiNameSub2( const char *file, const char *mes )
{
	FILE	*fpo;
	char	fileName[ MAX_FILENAME_LEN ], *p;

	SetTmpDirFile( fileName, KAIGI_TMP_FILE_NAME );
	if ( ( fpo = fopen( fileName, "a" ) ) == NULL ) {
		strcpy( FileName, fileName );
		error_open_file( "会議室の名前を得る" );			return;
	};
	fprintf( fpo, "%s\n", file );
	p= last_yen( file );	if ( p != (char *)file )	p++;
	fprintf( fpo, "%-13s%s\n", p, mes );
	fclose( fpo );
	GetKaigiNameNum++;
}

static	void	GetKaigiNameSub( const char *file )
{
	if ( isCATLOGFile( file ) == 0 )								return;
	switch( MesNum ) {
		case HP:		GetKaigiNameSub2( file, ForumNameLine );	break;
		case PATIO:		GetKaigiNameSub2( file, ForumNameLine );	break;
		case MAIL:
			GetKaigiNameGetHandle( file );
			sprintf( ForumNameLine, "MAIL:%-16s からのＭＡＩＬです", Handle );
			GetKaigiNameSub2( file, ForumNameLine );
			break;
		case ALL_MAIL:	GetKaigiNameSub2( file, ForumNameLine );	break;
		case BILL:		GetKaigiNameSub2( file, ForumNameLine );	break;
		case COLLECT_ID:											break;
		case LIB:		GetKaigiNameSub2( file, ForumNameLine );	break;
		case COLLECT_LIB:											break;
		case CLIP:		GetKaigiNameSub2( file, ForumNameLine );	break;
		default:			// フォーラムの会議室
			GetKaigiNameSub2( file, KNL[ MesNum ] );	break;
	};
}

// path はファイル名の時もある
int		GetKaigiName( const char *path, int startSw )
{
	FILE	*fpi;
	char	fileName[ MAX_FILENAME_LEN ];

	if ( startSw == YES ) {
		SetTmpDirFile( fileName, KAIGI_TMP_FILE_NAME );
		remove( fileName );
		GetKaigiNameNum = 0;
	};
	if ( ( fpi = fopen( path, "r" ) ) != NULL ) {
		fclose( fpi );
		GetKaigiNameSub( path );
	} else {
		CatlogFindFirst2( path, GetKaigiNameSub );
	};
	return( GetKaigiNameNum );
}

//	###########################################################################
//	##### MakeTreeMain ########################################################
//	###########################################################################

/********************************/
/* コメント関係の深さの最大値   */
/* * 2 は文字列として処理する為 */
/********************************/
#define		LEVEL_COMMENT	( 40 * 2 )

static	struct	CommentTreeData		Tree;
static	int		CommentLevel = 0;
static	char	MakeTreeSortLine[ LEVEL_COMMENT + 4 ];
static	int		ahureSw = FALSE;
static	int		newForumSw = TRUE;

static	int		MakeTreeSort1( int st0 );

/*********************************************************************/
/* st 以降の発言で moto と同じコメント元番号の発言のポインタ値を返す */
/*********************************************************************/
static	int		isComNum( int st, const SayLong sayNum, const SayLong moto )
{
	st++;
	for ( ; st < save_end ; st++ ) {
		if ( catlog[st].SayNum == (SayLong)0 )					continue;
		/* 削除してないデータ */
		if ( catlog[st].SayNum <= sayNum ) {
		/* MAIL , LIB は発言番号の順に並んでいない */
		if ( MesNum != MAIL )									break;
		};
		if (	catlog[st].ahure == 0x00
		&&		catlog[st].ComNum == moto
		)														return( st );
	};
	return( -1 );
}

static	void	MakeTreeSort3( const int st )
{
	SayLong		sayNum, comNum;
	char		id[ 20 ];

	CheckAbort();
	if ( CheckAbortSw == YES )								return;

	fseek( CatlogFpi, catlog[st].seek_ichi, SEEK_SET );
	fread( &catlogIndex, sizeof(struct CatlogIndex), 1, CatlogFpi );

	// 初期値
	Tree.indexSeek	= catlog[st].seek_ichi;		// ｲﾝﾃﾞｯｸｽ上の位置
	Tree.seek		= catlogIndex.seek;			// Seek位置

	if ( newForumSw == TRUE ) {
		newForumSw = FALSE;
		Tree.Level	=	-1;						// コメントのレベル
												// -1 : 会議室
												// -2 : フォーラム
		Tree.SayId		= 0L;					// 発言者ＩＤ
		Tree.SaySize	= 0L;					// 発言の大きさ
		Tree.SayLine	= 0L;					// 発言の行数
		Tree.SayNum		= (SayLong)0;			// 発言番号
		if ( MesNum == MAIL ) {
			strcpy( Tree.Mes, ForumNameLine );		// コメツリの表示行
		} else {
			strcpy( Tree.Mes, ForumNameLineSub );	// コメツリの表示行
		};
		*Tree.Handle= *Tree.Mes2 = '\0';
		fwrite( &Tree, sizeof(struct CommentTreeData), 1, CatlogFpo );
	};

	sayNum=catlog[st].SayNum;	comNum=catlog[st].ComNum;
	Long2Id( id, catlogIndex.SayId );
	if ( catlog[st].ahure != 0 ) {
//		sprintf( str, "%c%s◆%05u(%05u) %s %s %s"
		sprintf( str, "%c%s◆%05u(%05u) %s %s"
						, catlogIndex.kidoku
						, MakeTreeSortLine
						, sayNum
						, comNum
//						, id
						, catlogIndex.Handle
						, catlogIndex.Mes
		);
	} else {
//		sprintf( str, "%c%s%05u %s %s %s"
		sprintf( str, "%c%s%05u %s %s"
						, catlogIndex.kidoku
						, MakeTreeSortLine
						, sayNum
//						, id
						, catlogIndex.Handle
						, catlogIndex.Mes
		);
	};

	/***********************/
	/* １行 102 文字に制限 */
	/***********************/
	StrCut( str, 102 );

/*
	sprintf( YesNoMes, "\n既読スイッチは<%c>でした", catlogIndex.kidoku );
	PrintMessage( YesNoMes );
*/

	/* 題名（コメントツリー） comtree0.tmp に書き出す */
	Tree.Level		= CommentLevel;				// コメントのレベル
												// -1 : 会議室
												// -2 : フォーラム
	Tree.SayId		= catlogIndex.SayId;		// 発言者ＩＤ
	Tree.SaySize	= catlogIndex.SaySize;		// 発言の大きさ
	Tree.SayLine	= catlogIndex.SayLine;		// 発言の行数
	Tree.SayNum		= sayNum;					// 発言番号
	strcpy( Tree.Handle, catlogIndex.Handle );	// ハンドル
	strcpy( Tree.Mes, str );					// コメツリの表示行
	strcpy( Tree.Mes2, catlogIndex.Mes );		// 発言の標題
	fwrite( &Tree, sizeof(struct CommentTreeData), 1, CatlogFpo );
}

static	void	MakeTreeSort2( const int st1 )
{
	int			st2, sw;
	SayLong		sayNum;

	CheckAbort();
	if ( CheckAbortSw == YES )								return;

	/* この発言番号を保存 */
	sayNum = catlog[st1].SayNum;

	/****************************/
	/* 第１：この発言を表示する */
	/****************************/
	MakeTreeSortLine[ CommentLevel ] = '\0';	// 文字列をこのレベルに初期化

	/* st1 以後に同じコメント元番号を持つ発言がある？ */
	sw = isComNum( st1, sayNum, catlog[st1].ComNum );
	if (	CommentLevel != 0
	||		ahureSw != TRUE
	) {
		if ( sw > 0 ) {		strcat( MakeTreeSortLine, "┣" );		/* ある */
		} else {			strcat( MakeTreeSortLine, "┗" );		/* ない */
		};
	};
	MakeTreeSort3( st1 );						// この発言をファイルに書き出す
	MakeTreeSortLine[ CommentLevel ] = '\0';	// 文字列をこのレベルに初期化

	/* 第２：st1 をコメント元番号とする発言を探す */
	if ( sw > 0 ) {		strcat( MakeTreeSortLine, "┃" );		/* ある */
	} else {			strcat( MakeTreeSortLine, "　" );		/* ない */
	};
	CommentLevel += 2;	/* レベルを１上げる */
	/******************/
	/* レベルチェック */
	/******************/
//	if ( CommentLevel >= level_comment ) {
	if ( CommentLevel >= LEVEL_COMMENT ) {
		/* コメントの階層が深すぎる場合の処理 */
		/* この発言をコメント元番号とする発言の ahure を 0x01 にする */
		st2 = st1 ;
		while ((st2=isComNum(st2,sayNum,sayNum))>0)	catlog[st2].ahure=0x01;
	} else {
		/* この発言をコメント元番号とする発言を表示する */
		st2 = st1 ;
		while ((st2=isComNum(st2,sayNum,sayNum)) > 0 ) {
			MakeTreeSort1( st2 );
			CheckAbort();
			if ( CheckAbortSw == YES )		break;
		};
	};
	CommentLevel -= 2;	/* レベルを１下げる */
	/* 処理済の発言とする */
	catlog[st1].SayNum = (SayLong)0;	catlog[st1].ahure  = 0x00;
}

static	int		MakeTreeSort1( int st0 )
{
	int			st1, st2, sw;
	SayLong		moto, sayNum;

	CheckAbort();
	if ( CheckAbortSw == YES )							return( st0 );

	/* この発言の発言番号 */
	while( catlog[st0].SayNum  == (SayLong)0 ) {
		st0++;
		if ( st0 >= save_end )							return( st0 );
	};
	moto   = catlog[st0].ComNum;
	sayNum = catlog[st0].SayNum;

	for( st2 = st0 ; st2 < save_end ; st2++ ) {
		CheckAbort();
		if ( CheckAbortSw == YES )						break;
		/* 発言番号が０のものは無視する */
		if ( catlog[st2].SayNum == 0 )					continue;
		/* より小さな発言番号に当たったら終了 */
		if ( st2 != st0 ) {
			/* ＤＬ以外は会議室の名前を表示するように */
			if ( catlog[st2].SayNum <= sayNum ) {
				if ( CommentLevel == 0 )		newForumSw = TRUE;
			};
			break;
		};

		if ( CommentLevel == 0 ) {
			ahureSw = TRUE;
			for ( st1=st2 ; st1<save_end ; st1++ ) {
				sw = catlog[st1].ahure;
				if ( sw != 0x00	) {
					/* １行に溢れた発言の処理 */
					MakeTreeSort2( st1 );			/* この発言を表示する */
				};
			};
			ahureSw = FALSE;
			/* 1993.8.21 以下のチェックを追加            */
			/* CommentLevel が 0 の場合は 強制的に表示する */
			sw = catlog[st2].SayNum;
			if ( sw != 0 ) {
				catlog[st2].ComNum = 0;
				MakeTreeSort2( st2 );				/* この発言を表示する */
			};
			continue;
		};
		/* コメント元番号が異なれば無視する */
		sw = ( catlog[st2].ComNum != moto );
		if ( sw )											continue;
		MakeTreeSort2( st2 );						/* この発言を表示する */
	};
	/* 文字列をこのレベルに初期化する */
	MakeTreeSortLine[ CommentLevel ] = '\0';

	return ( st2 );
}

/* ベタツリー・モードの場合 */
static	void	MakeTreeMainBate( )
{
	int		i, start;
	SayLong	sayNum1, sayNum2;

	sayNum2= catlog[0].SayNum;
	start= FALSE;
	for ( i=0; i<save_end; i++ ) {
		sayNum1 = catlog[i].SayNum;
		if ( sayNum1 != 0 ) {
			if (	(	MesNum == HP
					||	MesNum == PATIO
					||	( 1<= MesNum && MesNum <= MAX_KAIGISHITSU )
					)
			&&		sayNum2 != sayNum1
			&&		start == TRUE
			) {
				Tree.Level	=	CommentLevel;			// コメントのレベル
														// -1 : 会議室
														// -2 : フォーラム
				Tree.seek		= 0L;					// Seek位置
				Tree.SayId		= 0L;					// 発言者ＩＤ
				Tree.SaySize	= 0L;					// 発言の大きさ
				Tree.SayLine	= 0L;					// 発言の行数
				Tree.SayNum		= (SayLong)0;			// 発言番号
				strcpy( Tree.Mes, "┣  ----- 削除された発言" );
														// コメツリの表示行
				*Tree.Handle= *Tree.Mes2 = '\0';
				fwrite( &Tree, sizeof(struct CommentTreeData), 1, CatlogFpo );
			};
			start= TRUE;
			sayNum2 = sayNum1 + (SayLong)1;
//			strcpy( MakeTreeSortLine, "  " );
			if ( i < save_end -1  ) {	strcpy( MakeTreeSortLine, "┣" );
			} else {					strcpy( MakeTreeSortLine, "┗" );
			};
			MakeTreeSort3( i );					// この発言をファイルに書き出す
		};
	};
}


static	int		TreeTmpFileNum;
int		MakeTreeMain( const char *fileName )
{
	int		i;
#ifdef	TMENU
	int		ptr;
#endif
	SayLong	sayNum;
	FILE	*fp;

	CheckAbortSw= NO;

	if ( fileName == NULL ) {							// イニシャライズ
		for ( i=0; i<100; i++ ) {
			sprintf( str, TREE_TMP_FILE_NAME, i );
			SetTmpDirFile( FileName, str );
			if ( ( fp= fopen( FileName, "r" ) ) == NULL ) {
				TreeTmpFileNum= i;
				return( i );
			};
			fclose( fp );
		};
		return( -1 );
	};

	if ( isCATLOGFile( fileName ) == 0 )				return( -1 );

#ifdef	TMENU
	/*	マウスを時計の形にする		*/
	MG_PushPtr( 81 , &ptr ) ;
#endif

	strcpy( Tree.ForumName, ForumName );
	Tree.MesNum = MesNum;
	strcpy( Tree.FileName, fileName );
	FileNum= GetCatlogFileNum( fileName );

	// インデックスファイルからツリーを作る
	i = Display;	Display= NO;	catlog_malloc( );	Display = i;
	save_start= save_end= 0;	get_idx_data( YES );
	SortCatlogData();			// 発言日時 → 発言番号 の順でソートする

	// コメント元関係でソートする
	/* ファイルのオープン */
	if ( CatlogFpi != NULL )	fclose( CatlogFpi );
	if ( CatlogFpo != NULL )	fclose( CatlogFpo );
	set_index_file_name( FileName, ForumName );
	if ( ( CatlogFpi= fopen( FileName, "rb") ) == NULL ) {
		goto MakeTreeMainJump;
	};
	sprintf( str, TREE_TMP_FILE_NAME, TreeTmpFileNum );
	SetTmpDirFile( FileName, str );
	if ( ( CatlogFpo= fopen( FileName, "ab") ) == NULL ) {
		er_open( FileName, 1, "MakeTreeMain");
	};

	/* 最初の発言番号よりも小さなコメント元番号は 0 にする */
	sayNum = catlog[0].SayNum;		catlog[0].ComNum = 0;
	for ( i=1; i<save_end; i++ ) {
		/* 1993.8.21 以下の判定を追加 */
		if ( catlog[i-1].SayNum > catlog[i].SayNum ) {
			/* この発言番号が前の発言番号よりも小さい場合 */
			/* sayNum を変更し catlog[i].ComNum を０にする */
			sayNum = catlog[i].SayNum;
			catlog[i].ComNum = 0;
		};
		if ( catlog[i].ComNum < sayNum ) catlog[i].ComNum = 0;
	};

	ahureSw = FALSE;
	newForumSw = TRUE;
	CommentLevel = 0;
	*MakeTreeSortLine = '\0';		i = 0;
	if ( MesNum == MAIL ) {
		MakeTreeMainBate( );
	} else {
		while ( ( i= MakeTreeSort1(i) ) < save_end ) {
			CheckAbort();
			if ( CheckAbortSw == YES )							break;
		};
	};

	fclose(CatlogFpo);		CatlogFpo= NULL;
	fclose(CatlogFpi);		CatlogFpi= NULL;

MakeTreeMainJump:

	/* 確保した領域を解放する */
	if ( catlog != NULL ) {
		free( catlog );			catlog= NULL;			max_catlog= 0;
	};

#ifdef	TMENU
	/*	マウスの形をもとに戻す		*/
	MG_PopPtr( ptr ) ;
#endif
	return( TreeTmpFileNum );
}


//	###########################################################################
//	##### DeleteIndexData #####################################################
//	###########################################################################
// インデックスから fileNum のデータを削除する
void	DeleteIndexData( char *forumName, int mesNum, int fileNum )
{
	char	idxName[ MAX_FILENAME_LEN ];
	char	bakName[ MAX_FILENAME_LEN ];
	char	tmpName[ MAX_FILENAME_LEN ];
	char	*p;
	FILE	*fpo, *fpi;

	// idxName → tmpName とコピーする
	MesNum= mesNum;
	set_index_file_name( idxName, forumName );
	strcpy( tmpName, idxName );
	p= last_comma( tmpName );	*p= '\0';	strcat( p, ".$$$" );
	strcpy( bakName, idxName );
	p= last_comma( bakName );	*p= '\0';	strcat( p, ".BAK" );

	if ( ( fpi= fopen( idxName, "rb" ) ) == NULL )				return;
	if ( ( fpo= fopen( tmpName, "wb" ) ) == NULL ) {
		fclose( fpi );
		er_open( tmpName, 1, "DeleteIndexData" );				return;
	};
	while( fread( &catlogIndex, sizeof(struct CatlogIndex), 1, fpi ) == 1 ) {
		if (	catlogIndex.FileNum != fileNum
		||		catlogIndex.MesNum != mesNum
		||		strcmp( catlogIndex.ForumName, forumName ) != 0
		) {
			fwrite( &catlogIndex, sizeof(struct CatlogIndex), 1, fpo );
		};
	};
	fclose( fpi );	fclose( fpo );

	// インデックス・ファイル名の拡張子を .BAK にする
	remove( bakName );
	// rename( old, New );
	rename( idxName, bakName );
	rename( tmpName, idxName );
	if ( GetFileSize( idxName ) <= 0 )		remove( idxName );
	remove( bakName );
}


//	###########################################################################
//	##### #####################################################################
//	###########################################################################


/* DIVIDE_END */

/* DIVIDE_START=..\common_a.c */
/*
	CATLOG の共通部分のサブプログラム群
*/

#include	"common.h"

// 外部関数		VC++ では必ず定義しておくこと
	void	er_memory( const char *com );
	void	er_open( const char *file, int mode, char *mes );

#ifdef	TMENU

#else

//	#define		__cplusplus
//	#include	"stdafx.h"
//	#include	"catlog.h"
//	#include	<afxwin.h>
//	#include	"printmes.h"
//	#include	<windows.h>

//	#typedef	int		long

#endif

char	*CopyWord( char *trg, char *src, int len )
{
	// 最初の空白を読み飛ばす
	src = skip_space( src );
	for ( ; *src && len > 0 ; ) {
		if ( *src == ';' || *src == ',' || *src == '.' )	break;
		if ( isspace( *src ) )								break;
		if ( iskanji( *src ) ) {
			if ( len > 1 ) {
				*trg++ = *src++;	len--;
				*trg++ = *src++;	len--;
			} else {
															break;
			};
		} else {
				*trg++ = *src++;	len--;
		};
	};
	*trg= '\0';
	// 規定の文字数以上の文字を読み飛ばす
	if ( *src == ';' || *src == ',' || *src == '.' ) {
		src++;		// デリミタを読み飛ばす
	} else {
		for ( ; *src ; src++ ) {
			if ( isspace( *src ) )		break;
		};
	};
	src= skip_space( src );
	return( src );
}

static	int	kanamoji[]={
	/* 0xa0 - 0xaf */
	0x2121,	0x2123,	0x2156,	0x2157,	0x2122,	0x2126,
	0x2572,	0x2521,	0x2523,	0x2525,	0x2527,	0x2529,
	0x2563,	0x2565,	0x2567,	0x2543,
	/* 0xb0 - 0xbf */
	0x213d,	0x2522,	0x2524,	0x2526,	0x2528,	0x252a,
	0x252b,	0x252d,	0x252f,	0x2531,	0x2533,	0x2535,
	0x2537,	0x2539,	0x253b,	0x253d,
	/* 0xc0 - 0xcf */
	0x253f,	0x2541,	0x2544,	0x2546,	0x2548,	0x254a,
	0x254b,	0x254c,	0x254d,	0x254e,	0x254f,	0x2552,
	0x2555,	0x2558,	0x255b,	0x255e,
	/* 0xd0 - 0xdf */
	0x255f,	0x2560,	0x2561,	0x2562,	0x2564,	0x2566,
	0x2568,	0x2569,	0x256a,	0x256b,	0x256c,	0x256d,
	0x256f,	0x2573,	0x212b,	0x212c
};

static	int	asciimoji1[]={	/* !"#$%&'()*+,-./  */
	0x2121,	0x212a,	0x2149,	0x2174,	0x2170,	0x2173,
	0x2175,	0x212d,	0x214a,	0x214b,	0x2176,	0x215c,
	0x2124,	0x215d,	0x2125,	0x213f
};

static	int	asciimoji2[]={	/* :;<=>? */
	0x2127,	0x2128,	0x2163,	0x2161,	0x2164,	0x2129
};

static	int	asciimoji3[]={	/* [\]^_ */
	0x214c,	0x216f,	0x214d,	0x2130,	0x2132
};

static	int	asciimoji4[]={	/* {|}~ */
	0x2150,	0x2143,	0x2151,	0x2131
};

static	int	to_jis_zen( int c )	/* JIS の全角コードに変換する */
{
	if ( isalnum(c) ) return(0x2300+c);	/* '0'-'9' 'A'-'Z' 'a'-'z' */
	if ( (0x20<=c) && (c<=0x2f) ) return( asciimoji1[c-0x20] );
	if ( (0x3a<=c) && (c<=0x3f) ) return( asciimoji2[c-0x3a] );
	if ( (0x5b<=c) && (c<=0x5f) ) return( asciimoji3[c-0x5b] );
	if ( (0x7b<=c) && (c<=0x7f) ) return( asciimoji4[c-0x7b] );

	if ( c=='`' ) return(0x212e);
	if ( 0xa0<=c && c<=0xdf ) return( kanamoji[c-0xa0] );
	return(c);
}

static	int	to_shift_zen( int c )	/* SHIFT_JIS の全角コードに変換する */
{
	int	c0;

	if ( c == ' ' )		return( 0x08140 );
	if ( isalnum( c ) ) {
		if ( c < 'a' )	return( 0x0821f + c );
		return( 0x0821f + c + 1 );
	};
	c0=to_jis_zen(c);
	if ( c0!=c )		return( FNT_jisToSjis( c0 ) );
	return(c);
}

void	to_shift_zen_s( const char *src , char *targ )
{
	int	c;

	while ( ( c = *src++ ) != 0 ) {
		c = to_shift_zen( c & 0x0ff );
		*targ++ = ( ( c >> 8 ) & 0x0ff );
		*targ++ = (   c        & 0x0ff );
	};
	*targ = '\0';
}

void	CalcLineColum( char *mes, int *line, int *colum, int maxColum )
{
	int		len;
	char	*p;

	*line = 0;
	while( *mes ) {
		for ( p= mes; *p ; p++ ) {
			if ( *p == '\n' )							break;
			if ( iskanji( *p ) ) {
				// maxColum から あふれる？
				if ( ( p - mes ) + 2 >= maxColum )		break;
				p++;
			};
			if ( p - mes >= maxColum )					break;
		};
		*line = *line + 1;
		len = p - mes;
		if ( len > *colum )		*colum = len;
	};
}

char	*KanStrCpy( char *trg, char *src, int klen )
{
	klen *= 2;
	while( klen > 0 ) {
		if ( *src == '\0' )		break;			// 文字列の方が短い場合
		if ( *src == '\n' ) {
			src++;				break;	 		// 改行文字の場合
		};
		if ( iskanji( *src ) ) {
			*trg++ = *src++;	klen--;			// 第１バイト
		};
		*trg++ = *src++;	klen--;				// 第１バイト or 第２バイト
	};
	*trg= '\0';
	return( src );
}

/*
	line から pattern の一致をチェックして
		一致した場合 → typ に pattern を設定
						pattern:Str の Str を ForumName にセット
						line を Str の次にセット
*/
static	
char	*analyze1Line2( char *typ, char *line, char *pattern, int mesNum )
{
	if ( matchstr2( line, pattern )==YES ) {
		strcpy( typ, pattern );		MesNum= mesNum;
		// ID or ForumName
		line= CopyWord( ForumName, line + strlen( pattern ) + 1, 8 );
	};
	return( line );
}

static	char	*
analyze1Line( char *trg, char *line, char *pattern, int sw )
{
	char	*p;

	for ( p= line ; *p ; ) {
		if ( matchstr2( p, pattern ) == YES ) {
			p += strlen( pattern );
			break;
		};
		for ( ; *p ; p++ )	if ( *p == ';' ) {	p++;	break;	};
	};
	if ( *p ) {
		if ( sw == YES ) {			// 標題
			strcpy( trg, p );
			without_crlf( trg );
			for ( ; *p ; p++ )	;		// p は '\0' を指す
		} else {
			while ( *p ) {
				if ( *p == ';' ) {	p++;	break;	};
				*trg++ = *p++;
			};
			*trg= '\0';
		};
	} else {
		return( line );			// 見つからなかった
	};
		return( p );			// 見つかった
}

int		analyzeFapxUpLine(
	char	*line, 
	char	*typ, 
	char	*fileName, 
	char	*title, 
	int		*horyu
) {
	char	str[ LINE ];
	char	*p, *q;

	*ForumName= '\0';

	if ( matchstr( line, "保留;" ) == YES ) {
		line += 5;
		*horyu= YES;
	} else {
		*horyu= NO;
	};

	if (	( p= analyze1Line2( typ, line, "HP", HP ) ) == line
	&&		( p= analyze1Line2( typ, line, "MAIL", MAIL ) ) == line
	&&		( p= analyze1Line2( typ, line, "PATIO", PATIO ) ) == line
	&&		( p= analyze1Line2( typ, line, "FORUM", MES ) ) == line
	) {
		MesNum= 0;
		return( NO );
	};
	ComNum= 0;
	if ( MesNum == MES ) {
		q= analyze1Line( str, p, "mes=", NO );
		if ( p != q ) {		MesNum= atoi( str );		p= q;		};
		q= analyze1Line( str, p, "reply=", NO );
		if ( p != q ) {		ComNum= atoi( str );		p= q;		};
	};
	p= analyze1Line( fileName, p, "file=", NO );
	p= analyze1Line( title, p, "title=", YES );
	return( YES );
}

int		MakeNewFapxResFileName( char *fileName, char *forumName )
{
	int		i;
	char	*p;
	FILE	*fp;

	if ( isRtBbsName( forumName ) == YES ) {
		CopyWord( fileName, rtBbsTmp.path, MAX_FILENAME_LEN );
		append_yen( fileName );
		strcat( fileName, "UP\\" );
	} else {
		strcpy( fileName, TmpDir );		append_yen( fileName );
	};
	check_and_make_output_path( fileName );
	p= fileName;	while( *p )		p++;

	SetToday( );	strcat( p,  ToDay );	p += 6;		*p= '\0';

	for ( i=0; i<100; i++ ) {
		*p= '\0';	sprintf( p, "%02d.RES", i );
		if ( ( fp= fopen( fileName, "r" ) ) == NULL )		return( YES );
		fclose( fp );
	};
	return( NO );
}

/*	path の下のディレクトリ名を tmpFile に書き出す
	tmpFile はテキスト・ファイルで、２行が１セットで
		１行目は対象のフルパス
		２行目はディレクトリ名
	が入る
*/
int		GetSubDirName( const char *path, const char *tmpFile )
{
			int		done ;
#ifdef	TMENU
			VECTOR		DTA;
			FMDTA		ffblk;
			FM_SaveDta( &DTA );
			FM_SetDta( &ffblk );
#else	// TMENU
	struct	_find_t		ffblk;
#endif
			char	fileName[ MAX_FILENAME_LEN ];
			FILE	*fp;

	sprintf( fileName, "%s\\*.*", path );
	done = FirstFile( fileName, FA_DIREC );	// Directory を指定
	SetTmpDirFile( fileName, tmpFile );
	if ( (fp= fopen( fileName, "w" ) ) == NULL ) {
		er_open( fileName, 1, "ディレクトリ名の検索" );		return( NO );
	};
	while ( ! done ) {
		if ( ( ATTR & FA_DIREC ) == FA_DIREC ) {
			if (	strcmp( ffblk.name , "." ) != 0
			&&		strcmp( ffblk.name , ".." ) != 0
			) {
				fprintf( fp, "%s\\%s\n", path, ffblk.name );	// ファイル名
				fprintf( fp, "%s\n", ffblk.name );				// 表示する文字
			};
		};
		done = NextFile;
	};
#ifdef	TMENU
	FM_RecovDta( &DTA );
#endif
	fclose( fp );
	return( YES );
}


/**********************/
/* 各発言のファイル名 */
/**********************/
void	set_file_name( char *fileName, char *forum, int mesNum, int count )
{
	char	file[ 32 ], *p ;

	if ( *forum == '\0' )		forum= "UN_KNOWN";
	p= OutDir;
	switch ( mesNum ) {
		case CLIP:
			sprintf( file , "CLIP\\CLIP.TX%d", count );				break;
		case PATIO:
			/* 1993.9.12 PATIOのディレクトリの修正 */
			if ( count < 10 ) {
				sprintf(file,"PATIO\\%s\\%s.PA%d",forum,forum,count);
			} else {
				sprintf(file,"PATIO\\%s\\%s.PA%c",forum,forum,'A'+count-10);
			};
			break;
		case HP:
			if ( count < 10 ) {
				sprintf(file,"HP\\%s\\%s.HP%d",forum,forum,count);
			} else {
				sprintf(file,"HP\\%s\\%s.HP%c",forum,forum,'A'+count-10);
			};
			break;
		case MAIL:
		case ALL_MAIL:
			if ( Mail1Sw == YES ) {
				sprintf( file , "NIFMAIL\\%s" , ALL_IN_1_MAIL_FILE_NAME );
			} else {
				sprintf( file , "NIFMAIL\\%s.ML%d", forum , count );
			};
			break;
		case BILL:	sprintf( file , "BILL\\BILL.BL%d", count );
			break;
		case COLLECT_ID:
			sprintf( file, "COLLECT\\%s.TX%d", SayId , count );
			break;
		case LIB:
			if ( *DLDir != '\0' )		p= DLDir;
			sprintf( file, "%s\\LIB%02d.TXT", forum, count);
			break;
		case COLLECT_LIB:
			if ( *DLDir != '\0' )		p= DLDir;
			sprintf( file, "collect\\%s\\%s.LIB", SayId, SayId );
			break;
		default:
			sprintf( file,"%s\\MES%02d_%02d.TXT",forum, mesNum, count );
			break;
	};
	strcpy( fileName, p );		append_yen( fileName );
	if ( CheckRtBbsLogSw == YES ) {
		strcat( fileName, "RT-BBS" );	append_yen( fileName );
	};
	strcat( fileName, file );
	check_and_make_output_path( fileName );
}

int		GetCatlogFileNum( const char *f_name )
{
	const	char	*p;
			int		res;

	p = (const char *)last_yen( f_name );
	if ( p != f_name )	p++;
	if ( matchstr( p, "MES%%_%%.TXT" ) == YES ) {	res = atoi( p + 6 );
	} else {
		while( *p )		p++;
		p--;
		if ( isdigit( *p ) ) {						res = (*p) & 0x0f;
		} else {									res = (*p) - 'A' + 10;
		};
	};
	if ( res < 0 )		res = 0;
	return( res );
}

/* 文字列の最後の空白を削除 漢字にも対応 */
void	EraseLastSpace( char *trg )
{
	char	*p;

	for ( p = trg ; *p ; p++ ) ;	p--;
/*
	p = trg + strlen( trg );
*/
	while ( p >= trg ) {
		if ( *p != ' ' ) {
					if ( *p != 0x40 )				break;
					if ( p <= trg )					break;
			p--;	if ( ( *p & 0xff ) != 0x81 )	break;
		};
		*p-- = '\0';
	};
}

void	PrintMessage( const char * );

void	error_return( char *mes )
{
	char	str1[ 1024 ];

	sprintf( str1, "\n%s。\n処理を続けます", mes );
	if ( get_yesno( str1 ) == NO )						error_end( );
}

/*
  MDDhmmss.LOG	:	Mの所を数字かA,B,Cである
					hの所を数字かA,B,C,D,E,F,G,H,I,J,K,L,P,Qであること
*/
static	int	isFAPXfileFL( const char *f_name )
{
	int		c;

	if ( matchstr(f_name,"?%%?%%%%") == NO )					return( NO );
	c = f_name[ 0 ];
	if ( ! isdigit( c ) ) {
		if ( c < 'A' || 'C' < c )								return( NO );
	};
	c = f_name[ 3 ];
	if ( ! isdigit( c ) ) {
		if ( c < 'A' || 'Q' < c )								return( NO );
	};
	return( YES );
}

int		isFAPXfile( const char *name )
{
	char	str1[ 16 ] , *p;

	/* ファイル名の長さは 10 文字以上？ */
	if ( strlen( name ) < 10 )			return( NO );

	strcpy( str1 , name );
	if ( isFAPXfileFL( str1 ) != YES )		return( NO );

	/* 拡張子は下の通り？ */
	p = last_comma( str1 );
	if ( strcmp( p , ".LOG" ) == 0 )		return( YES );
	if ( strcmp( p , ".RES" ) == 0 )		return( YES );
	if ( strcmp( p , ".UP" ) == 0 )			return( YES );
	if ( strcmp( p , ".EML" ) == 0 )		return( YES );
	if ( strcmp( p , ".NPB" ) == 0 )		return( YES );
	// 下のファイルは削除の対象から外す
	if ( strcmp( p , ".BML" ) == 0 )		return( YES );
	return( NO );
}

/****************************************************************************
＞          1         2         3         4         5
＞ 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234
＞ 343  NAA02244 92/06/08   57903   19 B CATLOG06.EXE NIFTY通信ログ編集ﾌﾟﾛｸﾞﾗﾑ
*****************************************************************************/
int		isLIBLine()
{
	if (	matchPSP(
				"???%  $$$%%%%% %%/%%/%% ??????% ???% ? ?"
			) == NO
	)															return( NO );
	/* type */
	if (	PSP[37] != 'T'
	&&		PSP[37] != 'B'
	&&		PSP[37] != 'N'
	)															return( NO );
	return( YES );
}

static	const	char	*DelimitterLine[] = {
	// フォーラムの入口の行
	"?:お知らせ            ?:掲示板      ?:電子会議",				//  0
	"?:データライブラリ    ?:会員情報    ?:リアルタイム会議",		//  1

	// メーテルリンクの入口
	"メーテルリンク  トップメニュー  TOP",							//  2
	" 1. ご案内                  (YOMU)       2. 電子メール",		//  3
	"　「メーテル広場」は、会員の方のコミュニケーションのための広場です。",
																	//  4
	"　初めての方は、【自己紹介の部屋】で自己アピールをどうぞ！",	//  5

	// 会議室の名前の行
	"−会議室?%  ",													//  6

	// 会議室の標題の行
	"%%%/%%%   $$$%%%%%  ???????????????? ??",						//  7
	"%%%/%%%   ********                   ??",						//  8
	"%%%%%/%%%%% $$$%%%%%  ???????????????? ?",						//  9
	"%%%%%/%%%%% ********                   ?",						// 10
	"(?%)   %%/%%/%% %%:%%",										// 11
	"       %%/%%/%% %%:%%",										// 12

	"?% ?????????????????  $$$%%%%%  %%/%% %%:%%",					// 13
	"?% ?????????????????  $$$%%%%%          %%/%%/%% %%:%%",		// 14
	"    題名：",													// 15

	"　あなたの御利用状況は次のとおりです",							// 16
	"　あなたのご利用状況は次のとおりです",							// 17
	"  あなたのご利用状況は次のとおりです",							// 18

	"%%%  [%%/%%/%% %%:%%]  $$$%%%%%      ",						// 19

	"データライブラリ (1:データ一覧  2:検索",						// 20

	"クリッピングサービス    CLIP",									// 21

	"??%   ?%/%% %%:%% ??: ",										// 22

	NULL
};

int		isCLIPLine( const char *psp )
{
	if ( matchstr(psp, DelimitterLine[22] ) == YES )		return( YES );
	return( NO );
}

int		isCLIPFirstLine( const char *psp )
{
	if ( matchstr( psp, DelimitterLine[21] ) == YES )		return( YES );
/*
	IfMatchStrYes("番号  提供日付        題名" )		return( YES );
*/
	return( NO );
}

int		isLIBFirstLine( const char *psp )
{
	if ( matchstr( psp, DelimitterLine[20] ) == YES )			return( YES );
	return( NO );
}

int		isHpHyoudaiLine( const char *psp )
{
	if( matchstr( psp, DelimitterLine[19] ) == NO )			return( NO );
	return( YES );
}

int		isBillFirstLine( const char *psp )
{
	if (	matchstr( psp, DelimitterLine[16] ) == YES
	||		matchstr( psp, DelimitterLine[17] ) == YES
	||		matchstr( psp, DelimitterLine[18] ) == YES
	) {
		return( YES );
	};
	return( NO );
}

int		isMailFirstLine( const char * psp, const char *nsp )
{
			/*       #123456789 123456  NAA02244  05/05 13:12 */
	if (	matchstr( psp, DelimitterLine[13] ) != YES
	&&		matchstr( psp, DelimitterLine[14] ) != YES
	) {
															return( NO );
	};
	if (	matchstr( nsp, DelimitterLine[15] ) == NO )		return( NO );
	return ( YES );
}

static	int		isMesHyoudaiLine_sub( const char *str )
{
					/* 発言の表題が異なる場合があるので修正 ↓ */
	if ( matchstr( str, DelimitterLine[ 7] )==YES )		return( YES );
	if ( matchstr( str, DelimitterLine[ 8] )==YES )		return( YES );
	if ( matchstr( str, DelimitterLine[ 9] )==YES )		return( YES );
	if ( matchstr( str, DelimitterLine[10] )==YES )		return( YES );
	return( NO );
}

int		isMesHyoudaiLine( const char *psp, const char *nsp )
{
	if ( isMesHyoudaiLine_sub( psp ) == NO )			return( NO );
	if ( matchstr( nsp, DelimitterLine[11] ) == YES )	return( YES );
	if ( matchstr( nsp, DelimitterLine[12] ) == YES )	return( YES );
	return( NO );
}

int		isMesForumNameLine( const char *psp )
{
	char	*p1;
	char	forumName[ 10 ];

	if ( matchstr( psp, DelimitterLine[6] ) == YES )			return( YES );
	/* F で始まらないフォーラムへも対応 92.7.17 */
	if ( matchstr( psp, "- $" ) != YES )						return( NO );
	/* フォーラム名 : 英数字 ? */
	p1= CopyAlnum8( forumName, psp + 2 );
	if ( matchstr( p1, "  MES(?%):" ) == NO )					return( NO );
	return( YES );
}

int		isMtlinkInputLine( const char *psp, const char *nsp )
{
	if (	matchstr( psp, DelimitterLine[2] ) == YES
	&&		matchstr( nsp, DelimitterLine[3] ) == YES
	)														return( YES );
	if (	matchstr( psp, DelimitterLine[4] ) == YES
	&&		matchstr( nsp, DelimitterLine[5] ) == YES
	)														return( YES );
	return( NO );
}

int		isMesInputLine( const char *psp, const char *nsp )
{
	if (	matchstr( psp, DelimitterLine[0] ) == YES
	&&		matchstr( nsp, DelimitterLine[1] ) == YES
	)															return( YES );
	if ( isMtlinkInputLine( psp, nsp ) == YES )					return( YES );
	return( NO );
}

int		isIDname( const char *str )
{
	if ( strlen( str ) != 8 )								return( NO );
	if ( matchstr(str, "$$$%%%%" ) == NO )					return( NO );
	return( YES );
}

void	error_open_file( char *function_name )
{
	char	str[ 256 ];

	sprintf(str,"%s で ファイル<%s>をオープンできません。\n" ,
		function_name ,
		FileName
	);
	PrintMessage( str );
	error_end( );
}

/********************************/
/* 日付情報を内部形式に変換する */
/********************************/
static	long	date_to_int_data[] = {
				12L * 31L * 24L * 60L ,		/* 年 */
				      31L * 24L * 60L ,		/* 月 */
				            24L * 60L ,		/* 日 */
				                  60L ,		/* 時 */
				                   1L		/* 分 */
	};

static	long	date_to_int_data_sub[] = {
				1L ,		/* 年 */
				1L ,		/* 月 */
				1L ,		/* 日 */
				0L ,		/* 時 */
				0L			/* 分 */
	};

long	date_to_long( char *date )
{
	long	d;
	int		i , s;

	d= 0L;
	s = 0;
	if (	MesNum == MAIL
	||		MesNum == ALL_MAIL
	) {
		/* 以下の判定は手抜きだ 1993.10.2 */
		if ( *date == '9' ) {		s = 0;
		} else {					s = 1;
		};
	};
	for ( i = s ; i < 5 ; i++ ) {
		d +=	(
					( *date & 0x0f ) * 10 + ( *(date + 1 ) & 0x0f )
					- date_to_int_data_sub[ i ]
				) * date_to_int_data[ i ];
		date += 2;
		if ( ! isdigit( *date ) )	break;
	};
	return( d );
}

void	long_to_date( char *date , long d )
{
	int		i, s;
	long	d2;
	char	str1[ 24 ];

	if (	d < date_to_int_data[0]
/*	1993.10.2 コメントアウト
	||		MesNum == MAIL
	||		MesNum == ALL_MAIL
*/
	) {			s = 1;
	} else {	s = 0;
	};
	*date= '\0';
	for ( i = s ; i < 5 ; i++ ) {
		d2 = d / date_to_int_data[ i ] + date_to_int_data_sub[ i ];
		d = d % date_to_int_data[ i ];
		sprintf( str1 , "%02d" , d2 );		strcat( date , str1 );
	};
}


// file の入出力の高速化のために
static	char	*sentinel;
static	FILE	*pool_fpi= NULL;
static	char	*catlog_pool=NULL;
static	char	*check_sentinel , *check_head ;

void	present_str_print()
{
	char	*p, ch;

	p= PSP + PSL ;
	ch= *p;
	*p= '\0';
	PrintMessage( "\n" );
	PrintMessage( PSP );
	*p= ch;
}

void	last_str_copy( char *str )
{
	strncpy(str,LSP,LSL); str[LSL]='\0';
};

void	present_str_copy( char *str )
{
	strncpy(str,PSP,PSL); str[PSL]='\0';
};

void	next_str_copy( char *str )
{
	strncpy(str,NSP,NSL); str[NSL]='\0';
};

static	char	crlf[ 3 ] = { 0x0d , 0x0a , '\0' };
void	catlog_fprintf( const char *targ )
{
	int	 len;

	len = strlen( targ );
	if ( len != 0 ) fwrite( targ , sizeof(char) , len , CatlogFpo );
	fwrite( crlf , sizeof(char) , 2 , CatlogFpo );
}

size_t	catlog_fwrite()
{
	size_t	len;

	if ( PSP == NULL ) {
		len= fwrite(CPDS, sizeof(char), sentinel - CPDS, CatlogFpo );
		if ( *(sentinel - 1 ) != 0x0a )			catlog_fprintf( "" );
	} else {
		len= fwrite(CPDS, sizeof(char), PSP - CPDS, CatlogFpo );
		if ( *(PSP - 1 ) != 0x0a )	 			catlog_fprintf( "" );
	};
	return( len );
}

/*****************************/
/* catlog_poolを解放して終了 */
/*****************************/
void	end_check_pool()
{
	fclose( pool_fpi );		pool_fpi= NULL;
	if ( catlog_pool != NULL ) {
		free( catlog_pool );
	} else {
		error_bug( "領域を確保していないのに解放しようとしているよ。");
	};
	catlog_pool = NULL;
}

static	void	delete_line( char *start , char *end )
{
	int	len;

	if ( start == end )		return;
	if ( start == NULL )	return;
	if ( end == NULL )		return;

	if ( start < catlog_pool || end < catlog_pool ) {
		sprintf(str,"delete_line 管理領域を破壊します<%ld> <%ld>",
			start - catlog_pool,
			end - catlog_pool
		);
		error_bug( str );	return;
	};

	len = end - start;
	memmove( start , end , check_sentinel - end );

	/********************/
	/* ポインタ類の更新 */
	/********************/
	if ( start < LLSP && LLSP < end ) {
		LLSP = start;
	} else {
		if ( end <= LLSP ) LLSP = LLSP - len;
	};

	if ( start < LSP && LSP < end ) {
		LSP = start;
	} else {
		if ( end <= LSP ) LSP = LSP - len;
	};

	if ( start < PSP && PSP < end ) {
		PSP = start;
	} else {
		if ( end <= PSP ) PSP = PSP - len;
	};

	if ( start < NSP && NSP < end ) {
		NSP = start;
	} else {
		if ( end <= NSP ) NSP = NSP - len;
	};

	if ( start < check_head && check_head < end ) {
		check_head = start;
	} else {
		if ( end <= check_head ) check_head = check_head - len;
	};

	if ( start < sentinel && sentinel < end ) {
		sentinel = start;
	} else {
		if ( end <= sentinel ) sentinel = sentinel - len;
	};

	if ( start < CPDS && CPDS < end ) {
		CPDS = start;
	} else {
		if ( end <= CPDS ) {
			CPDS = CPDS - len;
		};
	};

	/* 空いた領域を 0 で埋める */
/*
	for ( p=check_sentinel-len; p<check_sentinel ; p++ ) *p = '\0';
*/
}

static	int	catlog_fread_char;
static	int	catlog_fread_char_sw = NO;

static	int	catlog_fread( char *pool1 )
{
	int	c,len1,len2,sw;

	sw = 0;
	if ( catlog_fread_char_sw != NO ) {
		sw = 1;
		*pool1++				= catlog_fread_char;
		catlog_fread_char_sw	= NO;
	};

	len1 = check_sentinel - pool1;		/* ロードするバイト数 */
	if ( len1 < 0 ) {
		error_bug( "catlog_fread ちゃんと領域を確保してね。" );
		return( 0 );
	};

	if ( pool1 < catlog_pool ) {
		sprintf(str,"catlog_fread 管理領域を破壊しますよ。<%ld> ",
			pool1 - catlog_pool
		);
		error_bug( str );	return( 0 );
	};

	/* ロードしたバイト数 */
	len2 = fread( pool1 , sizeof(char) , len1 , pool_fpi );

	if ( len2 < len1 ) {
		c = fgetc( pool_fpi );		/* set EOF flag */
		if ( c != EOF ) {
			catlog_fread_char		= c;
			catlog_fread_char_sw	= YES;
		} else {
			catlog_fread_char_sw	= NO;
		};
	};

	sentinel = pool1 + len2;
	return ( len2 + sw );
}

static	int	load_sentinel()
{
	int	len;

	if ( catlog_pool <= CPDS ) {
		delete_line( catlog_pool , CPDS );
	};
	if ( sentinel == check_sentinel ) {
		error_bug("確保した作業領域より発言の方が大きいので、"
					"データをロードできません。"
		);
		return( 0 );
	};
	len = catlog_fread( sentinel );
	return( len );
}

static	char	*set_next_str()
{
	int	len;

	NSP = check_head;
	NSL = 0;

	if ( check_head == NULL )	return( PSP );

	if ( check_head >= sentinel ) {
		if ( feof( pool_fpi ) != 0 )	{		/* EOF */
			NSP = NULL;	NSL = 0;
			return( PSP );
		};
		/* 処理済みの行を削除 */
		len = load_sentinel();
		/* 以下は必要ないが……… */
		if ( len == 0 ) {			/* EOF */
			NSL = check_head - NSP;
			check_head = NULL;
			return( PSP );
		};
	};

	while ( *check_head != 0x0d ) {
		if ( *check_head == 0x1a ) {	/* ^Z */
			/* 処理済みの行を削除 */
			/* 空白にする */
			*check_head = ' ';
/*
			delete_line( check_head , check_head + 1 );
			continue;
*/
		};
		check_head++;
		if ( check_head >= sentinel ) {
			if ( feof( pool_fpi ) != 0 )	break;	/* EOF */
			/* 処理済みの行を削除 */
			len = load_sentinel();
			/* 以下は必要ないが……… */
			if ( len == 0 ) {			/* EOF */
				NSL = check_head - NSP;
				check_head = NULL;
				return( PSP );
			};
		};
	};
	NSL = check_head - NSP;			/* 0x0d は数えない */

	if ( *check_head == 0x0d )		check_head++;
	if ( *check_head == 0x0a )		check_head++;
	return( PSP );
}

/********************/
/* ポインタ群の更新 */
/********************/
char	*catlog_fgets()
{
	/* ファイルの中での位置 */
	if ( NSP != NULL && PSP != NULL ) {
		pool_seek_ichi += (NSP - PSP);
	};

	PoolGyou++;

	LLSL = LSL;
	LLSP = LSP;

	LSL = PSL;
	LSP = PSP;

	PSL = NSL;
	PSP = NSP;

	//	if ( PSP != NULL )	present_str_print();

	return set_next_str();		/* set next_str */
}

/***************************************************/
/* malloc() を使って catlog_pool[] の領域を確保する */
/***************************************************/
static	void	pool_malloc( size_t fsize )
{
	int	sw;
	size_t	max,min,tmp,tuika;

	PoolGyou = 0;

	/* 1993.3.24 JINX さんよりバグ報告
	*  fsize が小さいと 0x0d の後ろの 0x0a を追加できなくハングする
	*  tuika に 20 を加える
	*/
	tuika = fsize * 2 / 3 + 20;

	if ( ( catlog_pool = (char *)malloc( (fsize + tuika)*sizeof(char) )
	) != NULL ) {
		check_sentinel = catlog_pool + fsize;
		return;
	};

	max = fsize;	min = 0;	tmp = ( max - min ) / 2 + min;
	sw = NO;
	while ( sw == NO ) {
		if ( ( catlog_pool = (char *)malloc( (tmp + tuika)*sizeof(char) )
		) == NULL ) {	max = tmp;
		} else {	min = tmp;	free( catlog_pool );
		};
		tmp = ( max - min ) / 2 + min;
		if ( tmp < 1 ) {
			tuika = tuika / 2;
			if ( tuika == 0 ) {
				strcpy(str,"メモリーが足りません。");
				error_bug( str );	return;
			};
			max = fsize;	min = 0;
			tmp = ( max - min ) / 2 + min;
		};
		if ( max == min || max - 1 == min ) sw = YES;
	};
	catlog_pool = (char *)malloc( (tmp + tuika)*sizeof(char) );
	check_sentinel = catlog_pool + tmp;
}

/************************************/
/* FileName のオープンと領域の確保 */
/************************************/
int		initial_check_pool( const char *fileName )
{
	long	fsize;
	long	fsize2;

	if ( catlog_pool != NULL ) {
		error_bug( "initial_check_pool を２重に読んでいます");
	};

	fsize= GetFileSize( fileName );
	if ( fsize <= 0L )											return( NO );

#ifdef	TMENU
	pool_malloc( fsize );
#else
	if ( fsize < 30L * 1024L ) {		pool_malloc( (int)fsize );
	} else {							pool_malloc( 30 * 1024 );
	};
#endif

	check_head = catlog_pool;

	CPDS =	LLSP = LSP = PSP = NSP = catlog_pool;
			LLSL = LSL = PSL = NSL = 0;

	pool_seek_ichi = 0;	/* ファイルの中での位置 */

	if ( ( pool_fpi = fopen( fileName ,"rb" ) ) == NULL ) {
		end_check_pool();										return( NO );
	};

	setbuf( pool_fpi , NULL );	/* NON Buffered mode */

												//	ファイルをロードできない
	if ( (	fsize2 = catlog_fread(catlog_pool) ) <= 0 ) {
		end_check_pool();										return( NO );
	};

	if ( fsize == fsize2 ) fgetc( pool_fpi );	/* set EOF flag */

	set_next_str();										return( YES );
}

char	*skip_space( const char *str )
{
	forever {
		if ( *str == '\0' )								return( (char *)str );
		if ( isspace( *str ) ) {						str++;
		} else if ( strncmp( "　" , str , 2 ) == 0 ) {	str += 2;
		} else {										return( (char *)str );
		};
	};
}

char	*skip_digit( const char *p )
{
	if (	p != NULL
	&&		p != '\0'
	) {
		while( isdigit( *p ) ) p++;
	};
	return( (char *)p );
}

int		matchstr2( const char *trg, const char *form )
{
	while ( *form ) {
		switch( *form ) {
			case '*':	if ( *trg == '\0' )					return( NO );
						if ( *(form+1) == '\0' )			return( YES );
						form++;
						while( toupper( *form ) != toupper( *trg ) ) {
							if ( *trg == '\0' )				return( NO );
							trg++;
						};
						form--;	trg--;
						break;
			case '?':	break;
			default:	if ( toupper( *form ) != toupper( *trg ) )	return(NO);
						break;
		};
		form++;		trg++;
	};
	return( YES );
}

int		matchstr( const char *trg, const char *form )
{
	while ( *form ) {
		if ( *form != *trg ) {
			switch( *form ) {
				case '%':	if ( ! isdigit( *trg ) )	return( NO );
							break;
				case '$':	if ( ! isalpha( *trg ) )	return( NO );
				case '?':	break;
				default:	if ( *form != *trg )		return( NO );
			};
		};
		form++;		trg++;
	};
	return( YES );
}

void	StrCut( char *p1, int max )
{
	char	ch, *p2, *clear;

	p2= p1 + max;
	clear= p1;
	forever {
		clear= p1;
		ch= *p1 ;
		if ( ch == '\0' )		break;
		if ( ch == CR )			break;
		if ( iskanji( ch ) )	p1++;
		p1++;
		if ( p1 > p2 ) break;
	};
	*clear= '\0';
}

char	*CopyAlnum8( char *trg, const char *src )
{
	int		cnt;

	cnt= 0;
	while ( isalnum( *src ) ) {
		*trg++ = *src++;
		cnt++;		if ( cnt >= 8 )		break;
	};
	*trg = '\0';
	return( (char *)src );
}

char	*SkipAlnum8( char *src )
{
	int		cnt;

	for ( cnt=0 ; cnt< 8 ; cnt++ ) {
		if ( ! isalnum( *src ) )	break;
		src++;
	};
	return( src );
}

void	append_yen( char *trg )
{
	if ( *trg == '\0' )					return;
	while ( *trg )	trg++;
	if ( *(trg-1) != '\\' ) {	*trg++ = '\\';	*trg= '\0';		};
}

char	*last_comma( const char *str )
{
	const	char	*result;

	result = str;
	while ( *str ) {	if ( *str == '.' ) result = str;
						str++;
	};	return( (char *)result );
}

long	GetFileSize( const char *fileName )
{
	FILE	*fpi;
	long	res;

	res= -1L;
	if ( ( fpi = fopen( fileName, "r" ) ) != NULL ) {
		fseek( fpi, 0L, SEEK_END );
		res= ftell( fpi );
		fclose( fpi );
	};
	return( res );
}

static	char	FileCopyFileName[ MAX_FILENAME_LEN ];
static	FILE	*FileCopyFpi= NULL;
static	char	*FileCopyBuffer= NULL;
static	unsigned	long	FileCopyBufferSize= 0;
int		FileCopy(
	const int mesNum,
	const char *fileName,
	long start,
	long end,
	FILE *fpo
) {

	int		res;

#ifdef	TMENU
	long	len, size;

	size= end - start;
	// 領域を確保
	if (	FileCopyBuffer == NULL
	||		FileCopyBufferSize < size
	) {
		if ( FileCopyBuffer != NULL )		free( FileCopyBuffer );
		FileCopyBuffer= malloc( size + 10 );
		if ( FileCopyBuffer == NULL )		er_memory( "FileCopy" );
		FileCopyBufferSize= size;
	};
	// 入力ファイルのオープン
	if (	FileCopyFpi == NULL
	||		strcmp( FileCopyFileName, fileName ) != 0
	) {
		if ( FileCopyFpi != NULL )			fclose( FileCopyFpi );
		if ( ( FileCopyFpi= fopen( fileName, "rb" ) ) == NULL ) {
			er_open( fileName, 0, "FileCopy" );
		};
	};

	// seek
	fseek( FileCopyFpi, start, SEEK_SET );
	res= YES;
	// copy
	while ( size > 0L ) {
		/* ロードしたバイト数 */
		len = fread( FileCopyBuffer, 1, size, FileCopyFpi );
		/* ファイル末 */
		if ( len <= 0L )	break;
		if ( fwrite( FileCopyBuffer, 1, len, fpo) < len ) {
			// 書き込みが出来なかった場合
			PrintMessage(
				"\nファイルの書き込みが出来ませんでした。処理を中断します。"
			);
			CheckAbortSw= YES;
			res= NO;
		};
		size -= len;
	};

#else

	long	size;
	size_t	len, mallocSize;

	// end と start から コピーするサイズを得る
	size= end - start;
	if ( size > 65000L ) {			mallocSize= 65000L;
	} else {						mallocSize= ( size_t )size;
	};
	// 領域を確保
	if (	FileCopyBuffer == NULL
	||		FileCopyBufferSize < mallocSize
	) {
		if ( FileCopyBuffer != NULL )		free( FileCopyBuffer );
		FileCopyBuffer= (char *)malloc( mallocSize + 10 );
		if ( FileCopyBuffer == NULL )		er_memory( "FileCopy" );
		FileCopyBufferSize= mallocSize;
	};
	// 入力ファイルのオープン
	if (	FileCopyFpi == NULL
	||		strcmp( FileCopyFileName, fileName ) != 0
	) {
		if ( FileCopyFpi != NULL )			fclose( FileCopyFpi );
		if ( ( FileCopyFpi= fopen( fileName, "rb" ) ) == NULL ) {
			er_open( fileName, 0, "FileCopy" );
		};
	};

	// seek
	fseek( FileCopyFpi, start, SEEK_SET );
	// copy
	while ( size > 0L ) {
		/* ロードしたバイト数 */
		len = fread( FileCopyBuffer, 1, mallocSize, FileCopyFpi );
		/* ファイル末 */
		if ( len <= 0L )	break;
		if ( fwrite( FileCopyBuffer, 1, len, fpo) < len ) {
			sw= NO;
			break;
		};
		size -= (long)len;
	};

#endif

	if ( res != NO ) {
		/* 最後にデリミタを加える */
		if (	mesNum == PATIO
		||		( 1<= mesNum && mesNum <= MAX_KAIGISHITSU )
		) {
			fwrite( delimitter, 1, 4, fpo );
		};
	};
	return( res );
}

void	FileCopyEnd()
{
	if ( FileCopyFpi != NULL ) {
		fclose( FileCopyFpi );		FileCopyFpi= NULL;
	};
	if ( FileCopyBuffer != NULL ) {
		free( FileCopyBuffer );		FileCopyBuffer= NULL;
	};
	*FileCopyFileName= '\0';
	FileCopyBufferSize= 0L;
}

void	check_and_make_output_path( const char *path );

void	SetTmpDir( char *fileName )
{
	strcpy( fileName, TmpDir );		append_yen( fileName );
	strcat( fileName, "CATLOG\\" );
	check_and_make_output_path( fileName );
}

void	SetTmpDirFile( char *trg, const char *add )
{
	strcpy( trg, TmpDir );		append_yen( trg );
	strcat( trg, "CATLOG\\" );
	check_and_make_output_path( trg );
	strcat( trg, add );
}

void	SetToday( )
{
	struct	tm		*timeptr;
			time_t	secsnow;

	/********************************/
	/* 今日の日付をシステムから知る */
	/********************************/
	time( &secsnow );			/* 現在の時刻 */
	timeptr = localtime( &secsnow );	/* 構造体に変換 */
	sprintf( ToDay , "%02d%02d%02d00" ,
			timeptr->tm_year,
			timeptr->tm_mon + 1,	/* 月は 1 小さい */
			timeptr->tm_mday
	);
}

int		mallocIdxSub( long max0, long size0, char **idx )
{
	int		sw;
#ifdef	TMENU
	long	size, min, tmp, max;

	size= size0;	max= max0;		   	
	min = 0;	tmp = ( max - min ) / 2 + min;
	sw = NO;
	while ( sw == NO ) {
		if( (*idx= TL_malloc( size * tmp ))== NULL ) {
			max = tmp;
		} else {
			min = tmp;	TL_free(*idx);
		};
		tmp = ( max - min ) / 2 + min;
		if ( tmp < 1 )	return( 0 );
		if ( max == min || max - 1 == min ) sw = YES;
	};
	*idx = TL_malloc( size * tmp );
	return( tmp );
#else
	size_t	size, min, tmp, max;

	if ( size0 > 65000L ) {		size= 65000L;
	} else {					size= ( size_t )size0;
	};
	if ( max0 > 65000L ) {		max= 65000L;
	} else {					max= ( size_t )max0;
	};
	min = 0;	tmp = ( max - min ) / 2 + min;
	sw = NO;
	while ( sw == NO ) {
		if( (*idx= (char *)malloc( size * tmp ))== NULL ) {		max = tmp;
		} else {										min = tmp;	free(*idx);
		};
		tmp = ( max - min ) / 2 + min;
		if ( tmp < 1 )	return( 0 );
		if ( max == min || max - 1 == min ) sw = YES;
	};
	*idx = (char *)malloc( size * tmp );
	return( tmp );
#endif
}

char	*last_yen( const char *str )
{
	const	char	*result;

	result = str;
	while ( *str ) {	if ( *str == '\\' ) result = str;
						str++;
	};
	return( (char *)result );
}

void	without_crlf(char *str)
{
	if ( *str == '\0' )							return;
	while( *str )	str++;
	str--;
	if ( *str == '\n' )		*str= '\0';
}

char	*touppers( char *str0 )		/* 文字列を大文字に変換する */
{
	char	*p;

	p = str0;
	while ( *p ) {
		if ( iskanji( *p ) ) {			p++;
		} else {						*p = toupper( *p );
		};
		p++;
	};
	return( str0 );
}

//	###########################################################################
//	##### 以下 ＶＣ＋＋用のコード #############################################
//	###########################################################################

#ifndef	TMENU

void	WriteCATLOGMessage( const char *mes );

static	FILE	*WCMes_fp = NULL;
void	WriteCATLOGMessage( const char *mes )
{
	/* ここでファイルに書き出す */
	if (	*CatlogMesFileName != '\0'
	||		WCMes_fp != NULL
	) {
		if ( WCMes_fp == NULL ) {
			if ( ( WCMes_fp = fopen( CatlogMesFileName , "ab" ) ) == NULL ) {
				er_open( CatlogMesFileName, 2, "WriteCATLOGMessage" );
			};
		};
		fwrite( mes, 1, strlen( mes ), WCMes_fp );
		//	fwrite( CrLf, 1, 2, WCMes_fp );
		fflush( WCMes_fp );
	};
}

void	CloseCATLOGMessageFile()
{
	if ( WCMes_fp != NULL ) {
		fclose( WCMes_fp );		WCMes_fp = NULL;
	};
}

void	RemoveCATLOGMessageFile()
{
	CloseCATLOGMessageFile();
	remove( CatlogMesFileName );
}

int		get_yesno( char *mes )
{
			int		YesNoSw;
//	extern	void	WriteCATLOGMessage( const char *mes );

	WriteCATLOGMessage( mes );

//	int     WINAPI MessageBox(HWND, LPCSTR, LPCSTR, UINT);
	if ( MessageBox(0,mes,"YES,NO を指定してください",MB_YESNO) == IDOK ) {
		YesNoSw= YES;
		WriteCATLOGMessage( " ＹＥＳ" );
	} else {
		YesNoSw= NO;
		WriteCATLOGMessage( " ＮＯ" );
	};

	return YesNoSw ;
}

void	showKakunin( const char *mes )
{
	MessageBox( 0,"確認してください", mes, MB_OK | MB_ICONEXCLAMATION );
}

static	int		PrintMessageSw = NO;
static	char	PrintMessageMes[ 1024 ];
void	PrintMessage( const char *mes )
{
	WriteCATLOGMessage( mes );
	if ( *mes == '\n' ) {
		*PrintMessageMes= '\0';
		mes++;
	};
	strcat( PrintMessageMes, mes );
//	MMI_SendMessage( Message_MESSAGE, MM_SETMSG, 1, PrintMessageMes );
	MessageBox(0,mes,"確認して下さい",MB_OK);
	PrintMessageSw = YES;
}

void	error_end()
{
	CATLOG_exit( 1 );
}

void	error_bug( const char *mes )
{
	char	str[ 512 ];

	sprintf( str , "\nCATLOG %s のバグ<%s>です。"
		,Version,mes
	);
	showKakunin( str );
	error_end();
}

void	er_memory( const char *com )
{
	sprintf( str, "\n%s でメモリーが足りません", com );
	showKakunin( str );
	error_end();
}

void	er_open( const char *file, int mode, char *mes )
{
	char	str1[ 512 ];

	sprintf( str1, "\n%s で can't open→<%s> ", mes, file);
	switch( mode ) {
		case 0:	strcat( str1, "(read)" );	break;
		case 1:	strcat( str1, "(write)" );	break;
		case 2:	strcat( str1, "(append)" );	break;
	};
	showKakunin( str1 );
	error_end();
}

void	CATLOG_exit( int re )
{
	exit( re );
}

/*
spawnvp' : 未解決の外部ｼﾝﾎﾞﾙ
*/

// forumName を「読む」というメニューの下に張りつける Windows版
int		AppendReadLogMenu( char *forumName )
{
	if ( forumName == NULL ) {
		// Menu を削除する
		return( YES );
	};

	// 登録済？
	// 登録できる？
	// 土台のメニューを大きくする
	// メニュー・アイテムを追加する

	return( YES );
}

#endif
/* DIVIDE_END */

/* DIVIDE_START=..\common_c.c */
/*
	Check1File
		Check1FileRtBbs
			isBOADMes
				setIdHandle
		Check1FileCatlog
			DeleteIndexData
				GetCatlogFileNum
		検索したデータの登録
			checkSaveSayData
		発言の検索
			check_start_line
			isMesInputLine			checkForumMode
				initial_kaigishitsu_name();
				get_forum_name_last_str()
				checkSetLibNumber();
				checkSkipUselessLine();
				isLIBFirstLine → checkLibMain
				isMesForumNameLine
					get_forum_name( PSP , sub);
					get_mes_num_from_forum_name_line
					present_str_copy
				check_forum_mode_end
				check_forum_name_mode_loop
			isMesForumNameLine		checkForumNameMode
				initial_kaigishitsu_name();
				present_str_copy( ForumNameLineSub );
				get_forum_name
				checkSetLibNumber
				checkSkipUselessLine();
				isMesHyoudaiLine(PSP,NSP)
				check_forum_name_mode_loop
			isMesHyoudaiLine		checkHyoudaiLineMode
				initial_kaigishitsu_name();
				get_mes_now_number( PSP , now );
				checkSetLibNumber
				present_str_copy( MesNumberLine );
				save_1_say
				checkSkipUselessLine();
				isMesHyoudaiLine(PSP,NSP)
			isMailFirstLine			checkMail
				while (	isMailFirstLine(PSP,NSP) == YES ) {
				check_SearchSayDate
					checkSetLibNumber
					checkSkipUselessLine();
					SetTmpDirFile(fileName, ID_TMP_FILE_NAME );
				isMailFirstLine(PSP,NSP)
					checkCheckEnd()
				checkSaveStartMail( MAIL );
				isSearchId
					checkSaveStartMail( COLLECT_ID );
				checkSkipUselessLine();
			isBillFirstLine			checkBill
									checkHpMain
			isHpHyoudaiLine			checkHpLoop( forumName );
			isLIBFirstLine			checkLibMain(forumName );
			isCLIPFirstLine			checkClipMain
			isCLIPLine				checkClipMain
									checkPatioMain
*/

#include	"common.h"

//	###########################################################################
//	##### #####################################################################
//	###########################################################################
static		int		isRTNFileSw= NO;
static		int		QuoteAllSaySw = NO;

			/* 日付による検索 */
static		char	SearchSayStartDate[ 8 ];
static		int		SearchSayStartDateSw = NO;
static		char	SearchSayEndDate[ 8 ];
static		int		SearchSayEndDateSw = NO;

long	Id2Long( char *id )
{
	long	result;

	if ( *id == '\0' )		return( 0L );

	result = 0L;			result =          (long)( *id & 0x01fL );	id++;
	result= result << 5;	result = result | (long)( *id & 0x01fL );	id++;
	result= result << 5;	result = result | (long)( *id & 0x01fL );	id++;
	result= result << 17;	result = result | atol( id );
	return( result );
}

void	Long2Id( char *trg, long id )
{
	*trg++ = 0x40 | (char)( ( id >> 27 ) & 0x01fL );
	*trg++ = 0x40 | (char)( ( id >> 22 ) & 0x01fL );
	*trg++ = 0x40 | (char)( ( id >> 17 ) & 0x01fL );
	sprintf( trg, "%05ld", id & 0x1ffffL );
}


//	###########################################################################
//	##### #####################################################################
//	###########################################################################
static	void	disp_start_check_file( const char *f_name, long fsize )
{
	CollectFileNumber++;
	CollectFileSize += fsize;
#ifdef	TMENU
	sprintf( YesNoMes, "\n%5d:%-40s:%7ld (%9d) → ",
		CollectFileNumber,
		f_name,
		fsize,
		CollectFileSize
	);
	PrintMessage( YesNoMes );
#endif

	HatsugenSu = 0;
}

//	###########################################################################
//	##### #####################################################################
//	###########################################################################
static	char	*WithoutFileName[] = {
					IDX_FILE_NAME,					// ｲﾝﾃﾞｯｸｽ･ファイル
					DEF_FILE_NAME,					// catlog.def ファイル名
					DEL_FILE_TABLE_FILE_NAME,		// 削除ファイル名
					FORCE_DEL_FILE_TABLE_FILE_NAME,	// 強制削除ファイル名
					TMP_FILE_NAME,					// ﾃﾝﾎﾟﾗﾘｨ･ファイルの名前
					ID_TMP_FILE_NAME,				// ｢ＩＤ｣の tmp file 名
					DL_FILE_NAME,					// DL の名前
					KAIGI_FILE_NAME,				// 会議室の名前
					ID_HANDLE_FILE_NAME,			// ｢ＩＤ｣の     file 名
					KAIGI_TMP_FILE_NAME,			// ｢会議室｣のtmp file 名
					DL_TMP_FILE_NAME,				// ｢ＤＬ｣のtmp file 名
					CATLOG_TIME_FILE_NAME,			// 時刻調査用 tmp file
					BILL_FILE_NAME,					// 課金情報のファイル名
					DONE_FILE_NAME,					// 実行済みのファイル名
					"TITLE.TXT",					// FAPX が作るファイル
					"CONNECT.DAT",					// FAPX が作るファイル
					"RTC.MEN",						// FAPX が作るファイル
					"DOWNRATE.DAT",					// FAPX が作るファイル
//					"MESSEA.SEA",					// FAPX が作るファイル
					"MYFORUM.LOG",					// FAPX が作るファイル
					"UPLDRATE.DAT",					// FAPX が作るファイル
					NULL
				};
int		isWithoutSearchFile( const char *f_name, const char *ff_name )
{
			int		i ;
	const	char	*cp;
			char	fileName[ MAX_DIRS ], *p1, *p2;

	// CATLOG が作るファイル
	for ( i=0; SrchFile[i].fileName != NULL; i++ ) {
		if ( matchstr2( ff_name, SrchFile[i].fileName ) ==YES)	return(YES);
	};

	// 標準で読み飛ばす拡張子
	cp= ff_name;
	while( *cp ) {
		if ( *cp == '.' ) {		cp++;	break;	};
		cp++;
	};
	if ( cp ) {
		for( i=0; WithoutAttr[i] != NULL; i++ ) {
			if ( strcmp( WithoutAttr[i], cp ) == 0 )		return( YES );
		};
	};

	// 標準で読み飛ばすファイル名？
	for ( i=0; WithoutFileName[i] != NULL ; i++ ) {
		if ( strcmp( WithoutFileName[i], ff_name ) == 0 )	return( YES );
	};

	//	検索しないファイルに入っている？
	p1= WithoutSearchFile;
	while( *p1 ) {
		p2= fileName;
		while( *p1 && *p1 != ',' && *p1 != ';' ) *p2++ = *p1++;
		*p2= '\0';
		if ( *p1 == ',' || *p1 == ';' )	p1++;
		if ( *fileName ) {
			if ( strcmp(  f_name, fileName ) == 0 )		return( YES );
			if ( strcmp( ff_name, fileName ) == 0 )		return( YES );
			if ( matchstr2( ff_name, fileName ) ==YES)	return( YES );
		};
	};

	return( NO );
}

static	int		isSearchFile( const char *f_name, const char *ff_name )
{
			char	fileName[ MAX_DIRS ], *p1, *p2;

	//	検索するファイルに入っていない？
	if ( *SearchFile == '\0' )							return( YES );
	p1= SearchFile;
	while( *p1 ) {
		p2= fileName;
		while( *p1 && *p1 != ',' && *p1 != ';' ) *p2++ = *p1++;
		*p2= '\0';
		if ( *p1 == ',' || *p1 == ';' )	p1++;
		if ( *fileName ) {
			if ( strcmp(  f_name, fileName ) == 0 )		return( YES );
			if ( strcmp( ff_name, fileName ) == 0 )		return( YES );
			if ( matchstr2( ff_name, fileName ) ==YES)	return( YES );
		};
	};
	return( NO );
}

static	void	setForumNameLine( int mes )
{
	if ( *ForumName == '\0' )	strcpy( ForumName, "UN_KNOWN" );
	switch( mes ) {
		case PATIO:
			if ( matchstr( KNL[1], "PATIO:$$$%%%%%" ) == YES ) {
				strcpy( ForumNameLine, KNL[1] );
			} else {
				sprintf(ForumNameLine,"PATIO:%s のＰＡＴＩＯです", ForumName );
			};
			break;
		case HP:
			if ( *str == '\0' ) {
				sprintf(ForumNameLine,"HP:%s のＨＰです ", ForumName );
			} else {
				if ( matchstr(str, "HP:$$$%%%%%【" ) == YES ) {
					strcpy( ForumNameLine, str );
				} else {
					/* 1994.2.28 追加
						ForumNameLine は 80 バイト 超えないようにする
					*/
					StrCut( str, 80 );
										/*     1       */
										/* 123  23  45 */
					sprintf(ForumNameLine,"HP:%s【%s】",ForumName,str);
				};
				StrCut( ForumNameLine, 80 );
			};
			break;
		case MAIL:
			sprintf(ForumNameLine,"MAIL:%s からのＭＡＩＬです",ForumName );
			break;
		case LIB:
			sprintf(ForumNameLine,"LIB:%s のＤＬです",ForumName );
			break;
		case NEW:
			strcpy(ForumNameLine, "NEW: 今週のお知らせ" );
			break;
		case CLIP:
			strcpy(ForumNameLine, "CLIP: クリッピングサービス" );
			break;
		case BILL:
			strcpy(ForumNameLine, "BILL: 利用料金情報" );
			break;
		default:
			sprintf(ForumNameLine,"FORUM:%s",ForumName );
			break;
	};
}

/* 総数 以下を削除する */
static	void	StrCutBachOfSouSu( char *p )
{
	while( matchstr( p, " 総数 :%" ) == NO ) {
		if ( *p == '\0' )									return;
		p++;
	};
	*p= '\0';
}

void	addMesNum( int typ, int num0, int num1 )
{
	char	*p;

/*
>−会議室 7  【 絵の道具 】れいんぼう・ぱれっと  発言数 :675 未読 :0−
*/
	/* ｢  発言数 :｣以下を削除する */
	for ( p= KNL[num1] ; *p ; p++ ) {
		if ( matchstr( p, "  発言数 :" ) == YES ) {
			*p= '\0';
			break;
		};
	};

	/* 末尾の「-」を削除する */
	p= KNL[num1];	while( *p )		p++;
	if ( matchstr( p-2, " -" ) == YES ) {	p-= 2; *p = '\0';			};

	/* 末尾の日付を削除する */
	if ( matchstr( p-9, " %%/%%/%%" ) == YES ) {	p -= 9;		*p = '\0';
	};

	p= KNL[num1];
	/*                  123456789 123456789 1234567 */
	/*                 12     406 (  36)   02/01    */
	/*                  1     339 (   1)   02/05   */
	if ( matchstr( p, "?% ??????% (???%)   ?%/?%   " ) == YES ) {
		strcpy( p, p + 28 );
	} else	if (	matchstr( p, "- F$" ) == YES
			||		matchstr( p, "- BEGIN  " ) == YES
	) {
		/* - FTOWNS1  MES( 3): */
		p= SkipAlnum8( p + 2 );
		/*
		>- FRAV  LIB( 1):【画像ツール】富士通のパソコン用  94/05/29 -
		*/
							/* 123456789 */
		if (	matchstr( p, "  MES(?%):" ) == YES
		||		matchstr( p, "  LIB(?%):" ) == YES
		) {
			strcpy( KNL[num1], p + 10 );
		};
	};

	/* 「−会議室?%」を削除する */
	p= KNL[num1];
	/*               123456789 123 */
	if ( matchstr( p, "−会議室?%" ) == YES ) {
		p += 8;
		p= skip_space( p );		p= skip_digit( p );		p= skip_space( p );
		strcpy( KNL[num1], p );
	};

	// PATIO:$$$%%%%%  MES(%%):  を削除する
	p= KNL[num1];
				//     123456789 123456789 123456789
	if( matchstr( p, "PATIO:$$$%%%%%  MES(%%):" ) == YES ) {
		strcpy( p, p+24 );
	};

	/* 「− LIB %  」を削除する */
	p= KNL[num1];
				/*   123456789 */
	if ( matchstr( p, "− LIB %" ) == YES ) {
		p= skip_digit( p + 7 );		p= skip_space( p );
		strcpy( KNL[num1], p );
		/* 「 総数 :%」以下を削除する */
		StrCutBachOfSouSu( KNL[num1] );
	};

	if ( typ != LIB ) {
		if ( typ == PATIO ) {
			sprintf( str,"PATIO:%s  MES(%2d):%s", ForumName, num0, KNL[num1] );
		} else if	(	( 0<= typ && typ <= MAX_KAIGISHITSU )
					||	typ == MES
		) {
			sprintf( str, "- %s  MES(%2d):%s -", ForumName, num0, KNL[num1] );
		};
		/**********************/
		/* １行７８文字に制限 */
		/**********************/
		StrCut( str, 80 );
		strcpy( KNL[num1], str );
	};
	strcpy( ForumNameLineSub, KNL[num1] );
}

static	int		isCATLOGFileIsRTNFile( char *ptr )
{
	isRTNFileSw= NO;
	ptr= skip_space( ptr );
	while ( *ptr == '-' ) ptr++;
	if ( *ptr == '\0' )									return( NO );
	if ( strncmp( ptr, " List by FAPX", 13 ) != 0 )		return( NO );
	isRTNFileSw= YES;
	return( YES );
}

static	int		isCATLOGFileIsCATLOGFile( char *ptr )
{
	ptr= skip_space( ptr );
	while ( *ptr == '-' ) ptr++;
	if ( *ptr == '\0' )										return( NO );
	if (	strncmp( ptr, " Resort by CATLOG", 17 ) != 0
	&&		strncmp( ptr, " List by FAPX", 13 ) != 0
	)														return( NO );
	return( YES );
}

static	void	isCATLOGFileSub( FILE *fpi )
{
	/************************/
	/* ForumNameLine の設定 */
	/************************/
	/* まず２行目を読み込む */
	fgets( ForumNameLine, 80, fpi );	without_crlf( ForumNameLine );
	if( matchstr( ForumNameLine, " 会議室：" ) == YES ) {
		strcpy( KNL[0], ForumNameLine );
		/* LIB の場合は読み込む行数を揃えておく */
		if ( MesNum == LIB )	fgets( ForumNameLine, 80, fpi );
		*ForumNameLine='\0';
	} else {
		/* 会議室名の行を読み込む */
		/* ３行目を読み込む */
		fgets( str, 80, fpi );	without_crlf( str );
		strcpy( KNL[0], str );
	};

	switch( MesNum ) {
		case PATIO:
			addMesNum( PATIO, 1, 0 );
			strcpy( KNL[1], KNL[0] );
			break;
		case HP:
			if(matchstr(ForumNameLine,"%%%  [%%/%%/%% %%:%%]  $$$%%%%%      ")
				== YES
			) {				*str= '\0';
			} else {
				strcpy( str, ForumNameLine );
				if (	matchstr( KNL[0], 
							"%%%  [%%/%%/%% %%:%%]  $$$%%%%%      "
						) != YES
				) {
					strcpy( str, KNL[0] );
				};
				if (	matchstr( str, 
							"- HP:$$$%%%%%のHome Partyです"
						) == YES
				)	*str= '\0';
			};
			setForumNameLine( HP );
			addMesNum( HP, 0, 0 );
			break;
		case LIB:
			if ( LibNum <= 0 || 20 < LibNum ) {
				sprintf( YesNoMes, "\n LibNum(%d)が異常です(001)", LibNum );
				PrintMessage( YesNoMes );
				error_end( );
			};
			/****************************/
			/* ForumNameLine を修正する */
			/****************************/
			setForumNameLine( LIB );
			/********************************/
			/* ＤＬ名（会議室名）を設定する */
			/********************************/
			/* RTN ファイルの場合 */
			strcpy( KNL[LibNum], KNL[0] );
			if ( matchstr( KNL[LibNum], "- F$" ) == YES ) {
				addMesNum( LIB, LibNum, LibNum );
				break;
			} else if ( matchstr( KNL[LibNum], "− LIB %" ) == YES ) {
				addMesNum( LIB, LibNum, LibNum );
				break;
			};
			/* ４行読み込む */
			fgets( str, LINE, fpi );	fgets( str, LINE, fpi );
			fgets( str, LINE, fpi );	fgets( str, LINE, fpi );
						/*   123456789 */
			if ( matchstr( str, "− LIB %" ) == YES ) {
				StrCut( str, 80 );
				strcpy( KNL[LibNum], str );
				addMesNum( LIB, LibNum, LibNum );
			} else {
				while( atoi( str ) == 0 ) {
					if ( fgets( str, LINE, fpi ) == NULL )	break;
				};
				strcpy( KNL[LibNum], str + 39 );
			};
			without_crlf( KNL[LibNum] );
//			addMesNum( LIB, LibNum, LibNum );
			break;
		default:
			addMesNum( MesNum, MesNum, 0 );
			strcpy( KNL[MesNum], KNL[0] );
			break;
	};
	if ( *ForumNameLine == '\0' )	setForumNameLine( MesNum );
}

int		isCATLOGFile( const char *f_name )
{
	int		num;
	char	*p1;
	FILE	*fpi;

	*ForumName= *ForumName2= *ForumNameLine= *ForumNameLineSub= '\0';
	strcpy( ForumName, "UN_KNOWN" );
	isRTNFileSw= NO;
	num= 0;

	if ( ( fpi=fopen( f_name, "r" ) ) == NULL ) {	/* 起こり得ないエラー */
		er_open( f_name, 0, "isCATLOGFile" );
	};
	fgets( str, LINE, fpi );

	if ( matchstr( str, "CT_INDEX" ) == YES ) {
		/* isCtiFile の代わり */
		fclose( fpi );
		return( 0 );
	};


//	>- F*  MES(?%):*
	if ( matchstr( str, "- F$" ) == YES ) {
		p1= CopyAlnum8( ForumName, str + 2);
						//	 123456789
		if ( matchstr( p1, "  MES(?%):" ) == YES ) {
			without_crlf( p1 );
			sprintf( ForumNameLine, "＜%s＞    %s", ForumName, ForumName );
			strcpy( ForumNameLineSub, str );
			MesNum= num= atoi( p1 + 6 );
			fclose( fpi );		return( num );
		};
	} else if ( strncmp( str, "FAPX:", 5 ) == 0 ) {
		p1= CopyAlnum8( ForumName, str + 5 );
		if ( *p1 != '.' ) {			fclose( fpi );	return( 0 );	};
		p1++;
		MesNum = num = atoi( p1 );
	} else if ( matchstr( str, "FORUM:" ) == YES ) {
		p1= CopyAlnum8( ForumName, str + 6 );
		if ( isCATLOGFileIsCATLOGFile(str+30)==NO )	goto isCATLOGFileJump;
		while ( *p1 == ' ' ) p1++;
		if ( strncmp( p1, "MES:", 4 ) == 0 ) {				p1 += 4;
			num = atoi( p1 );
		} else if ( strncmp( p1, "LIB:", 4 ) == 0 ) {		p1 += 4;
			num = LIB;				LibNum= atoi( p1 );
		} else {									goto isCATLOGFileJump;
		};
		isCATLOGFileIsRTNFile( p1 + 3 );
		MesNum = num;
	} else if ( matchstr( str, "RT-BBS:" ) == YES ) {
		p1= CopyWord( ForumName, str + 7, 8 );
		if ( isCATLOGFileIsCATLOGFile(str+30)==NO )	goto isCATLOGFileJump;
		CheckRtBbsLogSw = YES;
		while ( *p1 == ' ' ) p1++;
		if ( matchstr( p1, "MES:" ) == YES ) {				p1 += 4;
			num = atoi( p1 );
		} else if ( matchstr( p1, "LIB:" ) == YES ) {		p1 += 4;
			num = LIB;	LibNum= atoi( p1 );
		} else {									goto isCATLOGFileJump;
		};
		isCATLOGFileIsRTNFile( p1 + 3 );
		MesNum = num;
	} else if ( strncmp( str, "MAIL:", 5 ) == 0 ) {
		p1= CopyAlnum8( str, str + 5 );
		if ( isCATLOGFileIsCATLOGFile( p1 )==NO )	goto isCATLOGFileJump;
		if ( isIDname( str ) == YES ) {
			strcpy( ForumName, str );	MesNum = num = MAIL;
			setForumNameLine( MAIL );
		};
	} else if (	strncmp( str, "HP:", 3 ) == 0 ) {
		p1= CopyAlnum8( str, str + 3 );
		if ( isCATLOGFileIsCATLOGFile( p1 )==NO )	goto isCATLOGFileJump;
		if ( isIDname( str ) == YES ) {
			strcpy( ForumName, str );	MesNum = num = HP;
		};
	} else if ( matchstr( str, "PATIO:$$$%%%%% MES(?%):" ) == YES ) {
		without_crlf( str );
		MesNum= num= PATIO;
		p1= CopyAlnum8( ForumName, str + 6 );
		while( *p1 != ':' )	p1++;
		strcpy( KNL[1], p1+1 );		addMesNum( PATIO, 1, 1 );
		strcpy( KNL[0], KNL[1] );
		setForumNameLine( PATIO );
		goto isCATLOGFileJump;
	} else if (	strncmp( str, "PATIO:", 6 ) == 0 ) {
		p1= CopyAlnum8( str, str + 6 );
		if ( isCATLOGFileIsCATLOGFile( p1 )==NO )	goto isCATLOGFileJump;
		if ( isIDname( str ) == YES ) {
			/* ForumName が PATIO の主催者 ID */
			strcpy( ForumName, str );	MesNum = num = PATIO;
			/* 1994.3.12 RTNリストへの対応 */
			isCATLOGFileIsRTNFile( p1 + 4 );
			setForumNameLine( PATIO );
		};
	} else if (	strncmp( str, "BILL:BILL", 9 ) == 0 ) {
		strcpy( ForumName, "BILL" );	MesNum = num = BILL;
	} else if (	strncmp( str, "COLLECT_ID:", 11 ) == 0 ) {
		p1= CopyAlnum8( str, str + 11 );
		if ( isCATLOGFileIsCATLOGFile( p1 )==NO )	goto isCATLOGFileJump;
		if ( isIDname( str ) == YES ) {
			strcpy( ForumName, str );	MesNum = num = COLLECT_ID;
		};
	} else if (	strncmp( str, "ALL-MAIL", 8 ) == 0 ) {
		if ( isCATLOGFileIsCATLOGFile(str+10)==NO )	goto isCATLOGFileJump;
		strcpy( ForumName, "ALL-MAIL" );	MesNum = num= ALL_MAIL;
	} else if (	strncmp( str, "CLIP", 4 ) == 0 ) {
		if ( isCATLOGFileIsCATLOGFile(str+10)==NO )	goto isCATLOGFileJump;
		strcpy( ForumName, "CLIP" );	MesNum = num = CLIP;
	} else if (	strncmp( str, "NEW", 3 ) == 0 ) {
		if ( isCATLOGFileIsCATLOGFile(str+10)==NO )	goto isCATLOGFileJump;
		strcpy( ForumName, "NEW" );		MesNum = num = NEW;
	};
	if (	num != 0
	&&		num != MAIL
	) {
		isCATLOGFileSub( fpi );
	};

	if ( isRTNFileSw == YES ) {
		MesNum= num= 0;				// 無視する
	};

isCATLOGFileJump:
	fclose( fpi );
	return( num );
}

static	long	SayDateCatlogFileStart;
static	long	SayDateCatlogFileEnd;

static	int		isHpHyoudaiLine2( )
{
	return( isHpHyoudaiLine( PSP ) );
}

static	int		isMesHyoudaiLine2( )
{
	return( isMesHyoudaiLine( PSP, NSP ) );
}

static	int		isMailFirstLine2()
{
	return( isMailFirstLine( PSP, NSP ) );
}

static	int		isBillFirstLine2( )
{
	return( isBillFirstLine( PSP ) );
}

static	int		isLIBFirstLine2( )
{
	return( isLIBFirstLine( PSP ) );
}

static	int		isCLIPLineSub()
{
	return( isCLIPLine( PSP ) );
}

/**********************************************************************
>          1         2         3         4  
> 123456789 123456789 123456789 123456789 12
>　あなたの御利用状況は次のとおりです
>
>　年月　　回数　　時間 (分) 　アクセス料金　サーチャージ　　料金合計 (円)
> 92/03      47          268          2,386             0            2,386
> 92/04      56          489          4,606             0            4,606
> 92/05月は課金データがありません
>日毎情報 (改行で表示  E:終了)
>＞[EOF]

****************
* 以下は新形式 *
****************
>年/月   回数  時間 (分)     基本料金 (円)       追加料金 (円)     料金合計 (円)
>92/07    104        715             6,408                   0             6,408
>                          無料使用権 (円)     課税対象額 (円)       請求額 (円)
>                                        0               6,408             6,600
>日毎情報 (改行で表示  E:終了)
>＞[EOF]
***********************************************************************/
/************************************************************************
　年月　　回数　　時間 (分) 　アクセス料金　サーチャージ　　料金合計 (円)
          1         2         3         4         5         6         7
 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12 
 92/03      47          268          2,386             0            2,386
 92/05月は課金データがありません

****************
* 以下は新形式 *
****************
年/月   回数  時間 (分)     基本料金 (円)       追加料金 (円)     料金合計 (円)
92/07    104        715             6,408                   0             6,408
*************************************************************************/
static	void	set_hatsugen_date_bill( char *ptr )
{
	char	*p1 , *p2;

	p1 = SayDate;							/* 発言の日付 */
	p2 = ptr;	*p1++ = *p2++; *p1++ = *p2++;	/* year */
	p2++;		*p1++ = *p2++; *p1++ = *p2++;	/* month */
	*p1 = '\0';
}

static	int		check_bill_second_line()
{
	if (	matchstr( PSP, BILL_SECOND_LINE1 ) == YES
	||		matchstr( PSP, BILL_SECOND_LINE2 ) == YES
	||		matchstr( PSP, BILL_SECOND_LINE3 ) == YES
	) {
		return( YES );
	};
	return( NO );
}

/*****************************************/
/*      ＰＡＴＩＯの１行目？             */
/*****************************************/
static	int		isPATIOFirstLine()
{
	if (	isMesHyoudaiLine(PSP,NSP) == YES
	&&		*( PSP + 5 ) == '/'		/* 新形式の発言形式だけに */
	)										return( YES );
	return( NO );
}

static	int		isPATIOEnd()
{
	char	*p;

	if ( PSL < 9 )										return( NO );

	if ( isPATIOFirstLine() == YES )					return( YES );

	/* 1994.3.30 追加 ちょっと乱暴だが……… */
	if ( matchPSP( "PATIO(?)>" ) == YES )				return( YES );

	if ( matchPSP( "PATIO(?)>" ) == YES
	&&		(	*( PSP + 6 ) == 'R'
			||	*( PSP + 6 ) == 'N'
			||	*( PSP + 6 ) == 'C'
			)
	) {
		/* PATIO(?)> : end 条件に入れることは問題があるかもしれない */
		if ( PSL == 9 )								return( YES );
		p = PSP + 9;
		if (	PSL > 12
		&&		(	strncmp( p , "GO " , 3 ) == 0
				||	strncmp( p , "go " , 3 ) == 0
				||	strncmp( p , "MOV" , 3 ) == 0
				)
		)	return( YES );
		if (matchstr(p,"−これ以上の発言はありません−")==YES)	return( YES );
	};
	/* 1993.8.9 追加 */
	if ( matchPSP("ID (改行のみ：自分のパティオ)")==YES)		return( YES );
	/* 1994.3.30 追加 */
	if (matchPSP( "−これ以上の発言はありません−")==YES)		return( YES );
	return( NO );
}

/****************************************************************************
＞          1         2         3         4         5
＞ 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234
＞[1993-01-08-15:09]
＞続き (改行で次文書　E:終了)
＞表示終了
*****************************************************************************/
static	int		isCLIPEnd()
{
	IfMatchStrYes("続き (改行で次文書　E:終了)")		return( YES );
	IfMatchStrYes("表示終了")    						return( YES );

	if ( isCLIPFirstLine( PSP ) == YES )				return( YES );
	if ( isCLIPLine( PSP ) == YES )						return( YES );
	return( NO );
}

static	int		isBILLEnd()
{
	if ( PSL == 0 )		return( NO );

	if ( isBillFirstLine(PSP) == YES )	return( YES );
	/**********************/
	/* 下は新形式でも同じ */
	/**********************/
			/* 123456789 123456789 123456789 */
	IfMatchStrYes("日毎情報 (改行で表示  E:終了)")		return( YES );
	if ( matchstr( PSP, "表示情報選択 (1:日毎合計表示  2:詳細表示  3:月毎合計再表示  E:終了)" ) == YES )							return( YES );

	return( NO );
}

static	int		isMailEnd()
{
	if ( isMailFirstLine(PSP,NSP) == YES )			return( YES );
	if ( matchPSP( "受信後 (1:削除" ) == YES )		return( YES );
	return( NO );
}

static	int		isHPEnd()
{
	char	*p;

	if ( PSL < 3 )												return( NO );
	if ( isHpHyoudaiLine(PSP) == YES )							return( YES );
	if ( strncmp( PSP , "HP>" , 3 ) == 0 ) {
		/* HP> : end 条件に入れることは問題があるかもしれない */
		if ( PSL == 3 )		return( YES );
		p = PSP + 3;
		if (	PSL >= 6
		&&		(	strncmp( p , "GO " , 3 ) == 0
				||	strncmp( p , "go " , 3 ) == 0
				||	strncmp( p , "MOV" , 3 ) == 0
				)
		)														return ( YES );
	};
/*
	if ( strncmp( PSP,"HP>MOV", 6 ) == 0 )						return( YES );
*/
	/* 1993.8.9 以下の文字列を追加した */
					/*123456789 123456789 123*/
	if ( strncmp(PSP,"ID (改行のみ：自分のHP)",23) == 0 )		return( YES );
	return( NO );
}

/********************************/
/* 会議室の終了時に現れる文字列 */
/********************************/
static	int		isMesEnd()
{
	if ( PSL == 0 )								return( NO );

	if ( isMesInputLine(PSP,NSP) == YES )		return( YES );

	/* - FTOWNS1 : ﾌｫｰﾗﾑ名  */
	if ( isMesForumNameLine(PSP) == YES )	 	return( YES );

	/* 発言の表題の行 */
	if ( isMesHyoudaiLine(PSP,NSP) == YES )		return( YES );

	/*           123456789 123456 */
	IfMatchStrYes( "電子会議 (1:発言" )			return( YES );
	IfMatchStrYes( "電子会議 (1:コメ" )			return( YES );
	IfMatchStrYes( "電子会議 (改行の" )			return( YES );
	IfMatchStrYes( "＞◆次頁はありません◆")	return( YES );
	IfMatchStrYes(   "◆次頁はありません◆")	return( YES );

	// デリミタ
	/* 下の命令は <Nakatani> さんより教えていただいた */
	if	( *(int *)PSP == 0x0a0d0820 )			return( YES );

	IfMatchStrYes("*****log整理")				return( YES );

	return( NO );
}

/*************************************/
/*      各発言の終了判定の入口       */
/*************************************/
static	int		checkCheckEnd()
{
	if ( PSP == NULL )									return( YES );
	if ( PSL == 0 )										return( NO );

	if ( isMesEnd() == YES )							return( YES );
	if ( isHPEnd() == YES )								return( YES );
	if ( isPATIOEnd() == YES )							return( YES );
	if ( isMailEnd() == YES )							return( YES );
	if ( isCLIPEnd() == YES )							return( YES );
	if ( isBILLEnd() == YES )							return( YES );

	/* ＞\n : end 条件に入れることは問題があるかもしれない */
/* 入れないことにした
	IfMatchStrYes("＞")									return( YES );
*/

	/* CCSCPY を使って整理した文書 */
	IfMatchStrYes("＊＊＊＊＊")							return( YES );

			/*  123456789 123456789 1 */
	IfMatchStrYes("ようこそNIFTY-Serveへ")					return( YES );

	return( NO );
}

/******************************************************************************
>＞LIB 数字
>としても、すぐに
>データライブラリ (1:データ一覧  2:検索  3:ｱｯﾌﾟﾛｰﾄﾞ（無料）  4:ﾀﾞｳﾝﾛｰﾄﾞ
>が表示されない場合があった。（ＦＴＯＷＮＳ１ 1992.8.14.ｱｸｾｽ ）
>　そこで、常に
>＞LIB 数字
>をチェックするように変更した。
******************************************************************************/
static	void	checkSetLibNumber()
{
	char	sub[ 10 ],*p1,*p2;

					/*   01234567 */
	if ( matchstr( PSP, "− LIB %") == YES ) {
		lib_number= atoi( PSP + 7 );
		if ( lib_number <= 0 || 20 < lib_number ) {	lib_number= 0;	return;
		};
/*
＞− LIB 16 【試作なんでも】  おきらくアップ歓迎 総数 :6   登録数 :5   −
*/
		present_str_copy( DL_name[ lib_number ] );
/* 上のまま記録した方が良いだろう
		p1= DL_name[ lib_number ] + 7;	while( isdigit( *p1 ) )		p1++;
		p1= skip_space( p1 );
		while( *p1 ) {
			if ( matchstr( p1, " 総数 :%" ) == YES )	break;
			p1++;
		};
		*p1= '\0';
*/
		return;
	};

	if ( strncmp( PSP , "＞" , 2 ) != 0 )		return;

	/* sub に３文字コピー */
	p1 = sub;	p2 = PSP + 2;
	*p1++ = *p2++;	*p1++ = *p2++;	*p1++ = *p2++;
	*p1 = '\0';

	/* to upper */
	touppers( sub );

	/****************************************/
	/* 以下の判定はかなり、いいかげんである */
	/* "＞LIB" という判定                   */
	/****************************************/
	if ( strcmp( sub , "LIB" ) == 0 ) {
		lib_number = atoi( PSP + 5 );
	};
	if ( strcmp( sub , "LX " ) == 0 ) {
		lib_number = atoi( PSP + 4 );
	};
}

/*******************************/
/* 3か月分の課金データをストア */
/*******************************/
// 3か月分の利用回数の合計を計算する 新形式でも同じ位置から計算する
static	int		CheckBillGetSayNum()
{
	int		i, sayNum;
	char	*p1, *p2;

	while ( check_bill_second_line() == NO ) {
		GET_LINE 0;		checkSetLibNumber();
		if ( matchstr(PSP+6,NO_BILL_MES )== YES )		break;
		if ( checkCheckEnd() == YES )					return 0;
	};

	// まず初期化
	sayNum = 0;
	// データを得る
	if (		matchstr( PSP  , BILL_SECOND_LINE1 ) == YES ) {
		/**********/
		/* 旧形式 */
		/**********/
		for ( i=0 ; i<3 ; i++ ) {
			GET_LINE(sayNum);		checkSetLibNumber();
			/* 旧形式 */
			if ( i == 0 )	set_hatsugen_date_bill( PSP + 1 );
			if (	matchPSP( " %%/%% ??????% ???????????% ?????????????% ????????????% ???????????????%" ) == YES
			) {
				sayNum += atoi( PSP + 6 );
			} else if ( matchPSP( " %%/%%月は課金データがありません" ) == YES
			) {
				;	// 何もしない
			} else {
				return (sayNum);
			};
		};
	} else if (	matchstr( PSP  , BILL_SECOND_LINE2 ) == YES
	||			matchstr( PSP+6,NO_BILL_MES) == YES
	) {
		/**********/
		/* 新形式 */
		/**********/
		i = 0;
		while ( i<3 ) {
			if ( matchstr( PSP, BILL_SECOND_LINE2 ) == YES ) {
				GET_LINE (sayNum);		checkSetLibNumber();
				if ( i == 0 )	set_hatsugen_date_bill( PSP );
				sayNum += atoi( PSP + 6 );
				i++;
			} else if (	matchstr(PSP+6,NO_BILL_MES)==YES){
				i++;
				GET_LINE(sayNum);		checkSetLibNumber();	/* 先読み */
			} else {
				if ( checkCheckEnd() == YES )	break; /* return( YES ); */
				GET_LINE(sayNum) ;		checkSetLibNumber();	/* 先読み */
			};
		};
	} else if (		matchstr( PSP  , BILL_SECOND_LINE3 ) == YES ) {
/*
>          1         2         3         4         5         6         7
> 123456789 123456789 123456789 123456789 123456789 123456789 123456789
>利用年月                 |    94年05月     |    94年06月     |    94年07月    
>利用回数                 |            68回 |            78回 |             1回
*/
				p1= SayDate;	p2= PSP + 30;
				*p1++ = *p2++;	*p1++ = *p2++;		// 年
				p2 += 2;
				*p1++ = *p2++;	*p1++ = *p2++;		// 月
				*p1= '\0';
				GET_LINE(sayNum) ;		checkSetLibNumber();
				sayNum= atoi( PSP + 26 ) + atoi( PSP + 44 ) + atoi( PSP + 62 );
	};
	return( sayNum );
}

static	int		isSearchId( const char *str )
{
	char	*p1, *p2;

	p1= SearchID;
	while( *p1 ) {
		p2= SayId;
		while( *p1 ) {
			if ( *p1 == ',' || *p1 == ';' ) {
				p1++;	break;
			};
			*p2++ = *p1++;
		};
		*p2= '\0';
		if ( *SayId == '\0' )	continue;
		if ( matchstr2( str, SayId ) == YES ) {		// 一致
			CopyAlnum8( SayId, str );
//			MesNum = COLLECT_ID;
			return( YES );
		};
	};
	*SayId = '\0';
	return( NO );
}

void	checkSetSayDate( int typ, const char *ptr )
{
	int		i, cnt;
	char	*trg;

	trg= SayDate;
	switch( typ ) {
		case HP:		ptr += 6;	cnt = 5;	break;
//		case PATIO:		ptr += 7;	cnt = 5;	break;
		case MES:		ptr += 7;	cnt = 5;	break;
		case LIB:		ptr += 15;	cnt = 3;	break;
		case NEW:		ptr += 6;	cnt = 3;	break;
		case CLIP:		ptr += 6;	cnt = 4;	break;
		case ALL_MAIL:
		case MAIL:
			if ( *(ptr+32) == ' ' ) {		ptr += 40;	cnt = 5;
			} else {						ptr += 32;	cnt = 4;
			};
			break;
		case BILL:
			cnt= 2;
			if (	matchstr( ptr, " %%/%%" ) == YES ) {
				ptr += 1;
			} else if ( matchstr( ptr, "%%/%%" ) == YES ) {
				;	// そのまま
			} else if ( matchstr( ptr, BILL_SECOND_LINE3 ) == YES ) {
				ptr += 30;
				*trg++ = *ptr++;	*trg++ = *ptr++;	ptr += 2;
				*trg++ = *ptr++;	*trg++ = *ptr;
				*trg = '\0';
				return;
			};
			break;
		case RTN:
			if ( ptr[16] == '/' ) {		ptr += 14;
			} else {					ptr += 16;
			};
			cnt= 4;		break;
	};
	for( i=0; i<cnt; i++ ) {
		*trg++ = *ptr++;		*trg++ = *ptr++;		ptr++;
	};
	*trg = '\0';
}

/***************************************************************************
	次のように発言の処理を行うことによって、「引用問題」の回避を行う。
	「次」というのは、次の発言の処理を行うことである。
		「- FRAV」あるいは、「1:お知らせ」の各モードによって処理は異なる。
	「無視」というのは、その行を無視することである。
		「- FRAV」あるいは、「1:お知らせ」の各モードによって処理は異なる。
	「終了」というのは、そのモードを終了することである。
 ･---------------------･---------･----------･------------･----------･ 
 | mode↓    出てきた→| xxx/yyy | - FRAV   | 1:お知らせ |  その他  | 
 |------------･--------+---------+----------+------------+----------･ 
 |            | 一致   |  終了   |   終了   |    終了    |   終了   | 
 | xxx/yyy    |--------+---------+----------+------------+----------･ 
 |            | 不一致 |  終了   |   終了   |    終了    |   終了   | 
 |------------+--------+---------+----------+------------+----------･ 
 |            | 一致   |  次     |   次     |    終了    |   終了   | 
 | - FRAV     |--------+---------+----------+------------+----------･ 
 |            | 不一致 |  無視   |   終了   |    終了    |   終了   | 
 |------------+--------+---------+----------+------------+----------･ 
 |            | 一致   |  次     |   次     |    終了    |   終了   | 
 | 1:お知らせ |--------+---------+----------+------------+----------･ 
 |            | 不一致 |  無視   |   無視   |    終了    |   終了   | 
 ･------------･--------･---------･----------･------------･----------･ 
****************************************************************************/
static	FILE	*SaveSayDataFpo= NULL;
static	char	SaveSayDataForumName[ 20 ];
static	int		SaveSayDataMesNum= 0;

void	CheckMainLoopEnd()
{
	if ( SaveSayDataFpo != NULL ) {
		fclose( SaveSayDataFpo );		SaveSayDataFpo= NULL;
	};
}

static	void	SaveSayDataFpoOpen( const int mesNum )
{
	char	fileName[ MAX_FILENAME_LEN ];
	char	sub[ 8 ];

	SetTmpDir( fileName );
	check_and_make_output_path( fileName );
	switch( mesNum ) {
		case HP:			strcat( fileName, ForumName );
							strcat( fileName, ".$HP" );		break;
		case PATIO:			strcat( fileName, ForumName );
							strcat( fileName, ".$PA" );		break;
		case ALL_MAIL:
		case MAIL:			strcat( fileName, ForumName );
							strcat( fileName, ".$MA" );		break;
		case BILL:			strcat( fileName, ForumName );
							strcat( fileName, ".$BL" );		break;
		case COLLECT_ID:	strcat( fileName, SayId );
							strcat( fileName, ".$CS" );		break;
		case LIB:			strcat( fileName, ForumName );
							strcat( fileName, ".$LB" );		break;
		case COLLECT_LIB:	strcat( fileName, SayId );
							strcat( fileName, ".$CL" );		break;
		case CLIP:			strcat( fileName, ForumName );
							strcat( fileName, ".$CP" );		break;
		default:			strcat( fileName, ForumName );
							strcpy( sub, ".$F?" );
							if ( 1 <= mesNum && mesNum <= 20 ) {
								sub[3]= 'A' + mesNum -1;
							} else {
								sub[2]= 'A' + mesNum / 26 ;
								sub[3]= 'A' + mesNum % 26 ;
							};
							strcat( fileName, sub );		break;
	};
	// ファイルのオープン
	if ( SaveSayDataFpo != NULL )	fclose( SaveSayDataFpo );
	if ( ( SaveSayDataFpo= fopen( fileName, "ab" ) ) == NULL ) {
		er_open( fileName, 1, "発言データＴＭＰファイル" );
	};
}

static	void	checkSaveSayData( const int mesNum )
{
			char		*p;
			char		str[ 1024 ];
			long		date1;
	struct	SrchFile	*srch;

	// インデックス整理の場合
	//   発言データは書き出さない
	if ( CheckMainCatlogMainSw == YES ) {
		if ( *ForumName == '\0' ) {
			strcpy( ForumName, "UN_KNOWN" );
		} else {
			/* フォーラム名の拡張子は削除する */
			p= last_comma( ForumName );
			if ( p != ForumName )	*p= '\0';
			/* フォーラム名が８文字よりも長い場合は８文字にする */
			StrCut( ForumName, 8 );
//			if ( strlen( ForumName ) > 8 )	ForumName[ 8 ] = '\0';
			if ( *ForumName == '\0' ) {
				strcpy( ForumName, "UN_KNOWN" );
			};
		};

		if (	SaveSayDataFpo == NULL
		||		strcmp( SaveSayDataForumName, ForumName ) != 0
		||		SaveSayDataMesNum != mesNum
		||		*SayId != '\0'
		) {
			strcpy( SaveSayDataForumName, ForumName );
			SaveSayDataMesNum= mesNum;
			SaveSayDataFpoOpen( mesNum );
		};
	};

	saveSayData.RtBbsSw		= CheckRtBbsLogSw;
	strcpy( saveSayData.FileName, SaveSayDataFileName );
	strcpy( saveSayData.ForumName, SaveSayDataForumName );
	saveSayData.MesNum		= mesNum;
	saveSayData.SayNum		= SayNum;
	saveSayData.ComNum		= ComNum;
	saveSayData.SayDate		= date_to_long( SayDate );
	saveSayData.SayId		= Id2Long( SayId );
	strcpy( saveSayData.ForumNameLine, ForumNameLine );
	strcpy( saveSayData.ForumNameLineSub, ForumNameLineSub );
	EraseLastSpace( Handle );
	strcpy( saveSayData.Handle, Handle );
	if ( Hyoudai == NULL ) {	*saveSayData.Mes = '\0';
	} else {
		strcpy( str, Hyoudai );
		StrCut( str, 44 );
		strcpy( saveSayData.Mes, str );
	};
	saveSayData.BStart		= BStart;
	saveSayData.BEnd  		= BEnd;
	saveSayData.GEnd		= PoolGyou;
	saveSayData.InyouSw		= InyouSw;

	if (	SearchIdSayMainSw == NO
	||		CheckAndMakeCatlog2IndexSw == YES
	||		(	SearchIdSayMainSw == YES
			&&	*SayId != '\0'
			&&	mesNum == COLLECT_ID
			)
	) {
		HatsugenSu++;		/* １つのファイルの発言の数 */
		// ファイルに書き出す
		if (	CheckMainCatlogMainSw == YES
		||		CheckAndMakeCatlog2IndexSw == YES
		) {
			fwrite(&saveSayData,sizeof(struct SaveSayData),1,SaveSayDataFpo);
		} else {
			date1 = date_to_long( SayDate );
			if (	mesNum != LIB
			&&		mesNum != COLLECT_LIB
			&&		ArrangeIndexDataOldestDate > date1
			) {
				ArrangeIndexDataOldestDate = date1;
			};
		};
		// 発言のサイズ
	};

	// 存在スイッチを YES にする
	switch( mesNum ) {
		case HP:			ExistHPSw= YES;				break;	// HP
		case PATIO:			ExistPATIOSw= YES;			break;	// PATIO
		case ALL_MAIL:
		case MAIL:			ExistMailSw= YES;			break;	// MAIL
		case BILL:			ExistBillSw= YES;			break;	// BILL
		case COLLECT_ID:	ExistCollectSaySw= YES;		break;	// Collect Say
		case COLLECT_LIB:	ExistCollectLibSw= YES;		break;	// Collect Lib
		case CLIP:			ExistCLIPSw= YES;			break;	// CLIP
		default:
			for ( srch= SrchFile; srch->fileName != NULL ; srch++ ) {
				if ( matchstr( srch->fileName, ForumName ) == YES ) {
					if ( mesNum == LIB )	srch++;
					*(srch->sw) = YES;
				};
			};
			if ( srch->fileName == NULL ) {
					if ( mesNum == LIB ) {
						ExistFORUMLibSw= YES;		break;	// LIB
					} else {
						ExistFORUMSw= YES;			break;	// Forum Say
					};
			};
			break;
	};

	InyouSw= NO;
}

static	int		Check1FileCatlogIsNewKaigi( int lastSayNum, int sayNum )
{
	if ( lastSayNum > sayNum ) {
		switch ( MesNum ) {
			case HP:
				last_str_copy( ForumNameLine );
				break;
			default:
				last_str_copy( ForumNameLineSub );
				break;
		};
		lastSayNum = sayNum;
	};
	return( lastSayNum );
}


static	void	getComNum( const char *p, int p_len, int ichi )
{
	int		i, ch, sw;

	for ( sw=0, i=0; i<p_len; i++, p++ ) {
		ch = *p;
		if ( iskanji( ch ) ) {				i++;	p++;
		} else if ( ch == '#' ) {
			/* 文中では RES が必要                 */
			/* ichi が 0 以外であれば # は無視する */
			if ( ichi == 0 ) {				sw= 1;		break;
			};
		} else if ( ch == 'R' || ch == 'r' ) {
			p++;
			if ( *p == 'E' || *p == 'e' ) {
				p++;
				if ( *p == 'S' || *p == 's' )	p++;
				p= skip_space( p );
				if ( *p == ':' )				p++;
				p= skip_space( p );
											sw= 1;		break;
			};
		};
	};
	if ( sw == 0 )												return;
	if ( *p == '#' )	p++;
	p= skip_space( p );
	if ( isdigit( *p ) )		ComNum= atoi( p );
}

static	int		Check1FileRtBbs( int ForumCopySw );

// CATLOG で整理したファイルから発言を検索する
static	int		Check1FileCatlog()
{
	if ( CheckRtBbsLogSw == YES ) {
		return	Check1FileRtBbs( NO );
	};

	int		(*func)( );
	char	*id ;
	long	sayDate;
	SayLong	lastSayNum;
	int		lineNumber;

	lastSayNum = 0;
	SayDateCatlogFileStart= SayDateCatlogFileEnd= 0;
	*SayId= '\0';

	Hyoudai= NULL;
	// isCATLOGFile
	switch( MesNum ) {
		case HP:			func= isHpHyoudaiLine2;
			Hyoudai = HyoudaiLine + 37;		// NAA02244
			break;
		case PATIO:			func= isMesHyoudaiLine2;
			break;
		case ALL_MAIL:
		case MAIL:			func= isMailFirstLine2;
			Hyoudai = HyoudaiLine + 10;
			break;
		case BILL:			func= isBillFirstLine2;
			break;
		case COLLECT_ID:		return( NO );
		case LIB:			func= isLIBFirstLine2;
							//     ↑ うまくいかないかもしれない
			break;
		case COLLECT_LIB:		return( NO );
		case CLIP:			func= isCLIPLineSub;			break;
		default:
			if ( 1 <= MesNum && MesNum <= MAX_KAIGISHITSU ) {
				func= isMesHyoudaiLine2;
			} else {
				// 扱えない形式である
				return( NO );
			};
			break;
	};
	forever {
		CPDS = LLSP;
		if ( (*func)( ) != YES ) {
			GET_LINE2	break;
			continue;
		};
		BStart				= pool_seek_ichi;
		saveSayData.GStart	= PoolGyou;
		//	SayNum, ComNum, char *SayDate を設定する
		id= NULL;	*SayId = '\0';
		SayNum = atoi( PSP );		ComNum = 0;
		*Handle= '\0';
		switch( MesNum ) {
			case HP:
				present_str_copy( HyoudaiLine );
				id= PSP + 23;
				CopyAlnum8( SayId, id );
				checkSetSayDate( HP, PSP );
				lastSayNum= Check1FileCatlogIsNewKaigi( lastSayNum, SayNum );
				getComNum( PSP, PSL, 0 );
				break;
			case ALL_MAIL:
			case MAIL:
				next_str_copy( HyoudaiLine );
				id= ForumName;
				CopyAlnum8( SayId, id );
				strncpy( Handle, PSP + 4, 16 );		Handle[ 16 ]= '\0';
				// ForumName の設定
				CopyAlnum8( ForumName, PSP + 22 );
				checkSetSayDate( MAIL, PSP );
				break;
			case BILL:
				// 3か月分の課金データをストア
				SayNum= CheckBillGetSayNum();
				break;
			case COLLECT_ID:
			case COLLECT_LIB:
				SayNum = 0;
				checkSetSayDate( MesNum, PSP );
				break;
			case LIB:
				strcpy( SayDate, "80/01" );
				forever {
					CPDS = LLSP;
					GET_LINE2	break;
					if ( isLIBLine() == YES ) {
						checkSetSayDate( LIB, PSP );	break;
					};
				};
				break;
			case CLIP:
				checkSetSayDate( CLIP, PSP );
				break;
			case PATIO:
			default:
				present_str_copy( HyoudaiLine );
				if ( *(PSP+3) == '/' ) {
					id = PSP + 10;
					strncpy( Handle, PSP + 20, 16 );	Handle[ 16 ]= '\0';
					Hyoudai = HyoudaiLine + 38;
				} else {
					id = PSP + 12;
					strncpy( Handle, PSP + 22, 16 );	Handle[ 16 ]= '\0';
					Hyoudai = HyoudaiLine + 39;
				};
				CopyAlnum8( SayId, id );
				if ( NSL > 21 ) {	ComNum= atoi( NSP + 23 );
				};
				checkSetSayDate( MES, NSP );
				lastSayNum= Check1FileCatlogIsNewKaigi( lastSayNum, SayNum );
				break;
		};
		lineNumber= 0;
		do {
			CPDS = LLSP;
			GET_LINE2	break;
			lineNumber++;
			if (	ComNum == 0
			&&		MesNum == HP
			&&		lineNumber < 4
			) {
				getComNum(PSP,PSL,0);
			};
		} while ( checkCheckEnd( ) == NO );
		BEnd= pool_seek_ichi;

		// 日付を登録する
		sayDate = date_to_long( SayDate );
		if ( SayDateCatlogFileStart == 0 ) {
				SayDateCatlogFileStart	= sayDate;
				SayDateCatlogFileEnd	= sayDate;
		} else {
			if ( sayDate < SayDateCatlogFileStart ) {
				SayDateCatlogFileStart	= sayDate;
			} else if ( SayDateCatlogFileEnd < sayDate ) {
				SayDateCatlogFileEnd	= sayDate;
			};
		};

		// 発言データを記録する
		checkSaveSayData( MesNum );

		if (	id != NULL
		&&		isSearchId( id ) == YES
		) {
			checkSaveSayData( COLLECT_ID );
		};
	};
	return( YES );
}

//	###########################################################################
//	##### RT-BBS のログを整理する #############################################
//	###########################################################################
static	int		Check1FileRtBbs( int ForumCopySw );

#define	ESC	0x1b

char	*SkipEsc( char *trg)
{
	char	*p;
	char	c1, c2, c3, c4;

	if ( *trg != ESC )					return( trg );

	c1= *(trg+1);	c2= *(trg+2);	c3= *(trg+3);	c4= *(trg+4);
	switch( c1 ) {
		/* ESC , G , Ps */
		case 'G':
			p= trg + 2;	while( isdigit( *p ) )	p++;
			return( SkipEsc( p ) );
		/* ESC , ? | 1 | 2 | 3 | # | " | * | D | E | M | R | T | Y */
		case '*':	case '?':	case '1':	case '2':	case '3':
		case '#':	case '"':	case 'D':	case 'E':	case 'M':
		case 'R':	case 'T':	case 'Y':
			return( SkipEsc( trg + 2 ) );
		/* ESC , ) , 0 | 3 */
		case ')':
			switch( c2 ) {
				case '0':	case '3':
					return( SkipEsc( trg + 3 ) );
				default:			break;
			};
			break;
		/* ESC , = | . , Pn , Pm */
		case '=':	case '.':
			return( SkipEsc( trg + 4 ) );
		default:										break;
	};

	if ( c1 != '[' )									return( trg );

	/* ESC , [ */
	if ( isdigit( c2 ) ) {
		p= trg + 2;		while ( isdigit( *p ) )		p++;
		switch( *p ) {
			case 'A':	case 'B':	case 'C':	case 'D':
			case 'J':	case 'K':	case 'L':	case 'M':
			case 'm':	case 'n':	case 'v':
				return( SkipEsc( p + 1 ) );
			case ';':
				while( *p == ';' ) {
					p++;	while ( isdigit( *p ) )		p++;
				};
				switch( *p ) {
					case 'R':	case 'H':	case 'f':
					case 'm':	case 'p':
						return( SkipEsc( p + 1 ) );
					default:							break;
				};
				break;
			default:									break;
		};
		return( trg );
	};

	switch( c2 ) {
		/* ESC , [ , K | u | s | m */
		case 'K':	case 'u':	case 's':	case 'm':
			return( SkipEsc( trg + 3 ) );
		case '>':
			/* ESC , [ , > , 1 | 3 | 5 , l | h */
			switch( c3 ) {
				case '1':	case '3':	case '5':
					if ( c4=='l' || c4=='h' )	return( SkipEsc( trg + 5 ) );
				default:							break;
			};
			break;
		case '=':
			switch( c3 ) {
				case '0':	case '1':	case '2':
				case '3':	case '7':
					if ( c4=='l' || c4=='h' )	return( SkipEsc( trg + 5 ) );
					break;
				default:							break;
			};
			break;
		/* ESC , [ , ? , 7 , l | h */
		case '?':
			if ( c3 == '7' ) {
				if ( c4 == 'h' || c4 == 'l' )	return( SkipEsc( trg + 5) );
			};
			break;
		default:									break;
	};

	return( trg );
}

static	char	*WaitStr( char *trg, char *form )
{
	trg= SkipEsc( trg );
	while( matchstr( trg, form ) != YES ) {
		if ( *trg == CR )				return( NULL );
		trg++;
		trg= SkipEsc( trg );
	};
	return( trg );
}

static	char	*WaitChar( char *str, char ch )
{
	str= SkipEsc( str );
	while( *str != ch ) {
		if ( *str == CR )				return( NULL );
		str++;
		str= SkipEsc( str );
	};
	return( str );
}

static	char	*NextCharOf( char ch, char *str)
{
	str= WaitChar( str, ch );
	if ( str != NULL )	str= SkipEsc( str + 1 );
	return( str );
}

/* 標題の部分を取り出す */
static	void	setHyoudaiLine( char *src, int sw )
{
	char	*trg;

	trg= str;
	while( *src != CR ) {
		src= SkipEsc( src );
		if (	sw != YES
		&&		(	matchstr( src, "検索中" ) == YES
				)
		)			break;
		*trg++ = *src++;
	};
	*trg = '\0';
	StrCut( str, 44 );
	strcpy( HyoudaiLine, str);
}

static	void	setBoadName()
{
	char	*p;

	p= NextCharOf( '#', PSP );	/* '#' の次の文字 */
	MesNum = LibNum= atoi( p );
	p= NextCharOf( ' ', p );	/* ' ' の次の文字 = ForumName */
	p= WaitChar( p, ' ' );
	while( *p == ' ' )	p= SkipEsc( p + 1 );	/* skip ' ' */
	setHyoudaiLine( p, NO );				/* 題名のセット */
	/* 右側の「 」を削除する */
	p= HyoudaiLine;
	while( *p ) p++;		/* ポインタを右端に */
	while( *(--p) == ' ' )	*p= '\0';
	/* 右側の「･」を削除する */
	while( *p == '･' )	*p-- = '\0';
	/* 右側の「 」を削除する */
	while( *p == ' ' )	*p-- = '\0';
}

static	long	WithOutEsc( char *start, char *end )
{
	char	*p0, *p1;
	size_t	cnt;

	cnt= 0;
	for ( p0= start ; p0 < end ; p0++ ) {
		/* まず ESC を見つける */
		if ( *p0 == ESC ) {
			/* 正しい ESC シーケンスになっている？ */
			p1 = SkipEsc( p0 );
			if ( p0 != p1 ) {
				/* 正しい ESC シーケンスである */
				memmove( p0 , p1 , end - p1 );
				cnt += (p1 - p0);
				end -= (p1 - p0);
				/* ESC が続く場合への対処 */
				p0--;
			};
		};
	};
	/* 後ろを NULL で詰める */
	memset( end , 0, cnt );
	/* 残った文字数 */
	return( end - start );
}

static	int		isLIBMes()
{
	FILE	*fpo;
	char	fileName[ MAX_FILENAME_LEN ];

	sprintf( fileName, "%sLIB%05d.tmp", TmpDir, LibNum );
	if ( ( fpo= fopen( fileName, "a" ))== NULL ) {
		er_open( fileName, 1, "isLIBMes" );
	};

	/* 最後の区切り */
	forever {
		GET_LINE2														break;
		if ( matchstr( PSP, "ファイルが存在しません。" ) == YES )		break;
		if ( matchstr( PSP, "???% ? ???????????? ???%K? ??% ")!=YES)	break;
		present_str_copy( str );
		WithOutEsc( str, str + strlen( str ) );
		StrCut( str, 78 );
		fprintf( fpo, "%s\n%s\n", HyoudaiLine, str );
		HatsugenSu++;
	};

	if (	matchstr( PSP, "---- - ------------ ------ --- ------------------------------------------------" ) == YES
	||		matchstr( PSP, "---- - ------------ ----- ---- ------------------------------------------------" ) == YES
	) {
		GET_LINE2	;
	};

	fclose( fpo);	fpo= NULL;		return( NO );
}

static	char	*SkipLeftMes( char *PSP )
{
	char	*p0;

	p0= NextCharOf( ':', PSP );			/* ':' の次の文字へのポインタ */
	p0= SkipEsc( p0 + 1 );				/* skip ' ' */
	return( p0 );
}

static	void	setIdHandle( char *src )
{
	int		i;
	char	*trg;

	src = CopyAlnum8( SayId, SkipEsc(src) );

	// ハンドルのコピー Handle
	trg = Handle;
	src= NextCharOf( '[', src );
	for ( i=0; i < 16 ; i++ ) {
		if ( *src == ']' )			break;
		if ( iskanji( *src ) ) {	*trg++ = *src++;		i++;		};
		*trg++ = *src++;
	};
	/* 右側の空白を削除する */
	while ( *( trg -1 ) == ' ' )	trg--;
	*trg= '\0';
}

static	void	set_hatsugen_date( )
{
	int		i;
	char	*trg, *p;

	p= SkipLeftMes( PSP );
	trg= SayDate;
	for( i=0; i < 6 ; i++ ) {
		p= SkipEsc( p );		*trg++ = *p++;
		p= SkipEsc( p );		*trg++ = *p++;
		p= SkipEsc( p );		p++;
	};
	*trg = '\0';
	for ( trg= SayDate; *trg ; trg++ ) {
		if ( *trg == ' ' )	*trg= '0';
	};
}

/*
>Mail stacks:  24/  47 (Remains:  23)    [Forward mode]
>============================================================= 93/11/04  3:36:31
>Section : Private mail
>Sender  : ALS00069 [　摩耶  ]  Reciever: ALS03223 [ＬＲＡ．]
>Date    : 93/11/03  9:28:03
>Subject : メールでは、お久しぶりです
>-------------------------------------------------------------------------------
*/
static	int		isMAILMes( )
{
	char	*p;

	MesNum = MAIL;
	SayNum = 1;				/* 常に1ということにしておく */

	/* ボードの名前の行を読み飛ばす */
	GET_LINE2												return( NO );

			/*     1         2         3         4          */
			/*   89 123456789 123456789 123456789 123456789 */
	if (
		matchstr( PSP, "????????: $$$????? [????????]  Reciever: $$$????? [????????]" ) != YES
	&&	matchstr( PSP, "????????: $$$????? [????????????]  Reciever: $$$????? [????????????]" ) != YES
	&&	matchstr( PSP, "????????: $$$%%%%% [????????????????]  Reciever: $$$%%%%% [????????????????]" ) != YES
	&&	matchstr( PSP, "???????? : $$$????? [????????]  Reciever: $$$????? [????????]" ) != YES
		/* ↓ 1994.3.4 追加 */
	&&	matchstr( PSP, "????????: $$$????? [????????]  受 信 者: $$$????? [????????]" ) != YES
	&&	matchstr( PSP, "?????????: $$$%%%%% [??????????]  |  受信者   : $$$%%%%% [??????????]" ) != YES
	)														return( NO );
		p= SkipLeftMes( PSP );
		/* ↓ ＩＤ */
		strncpy( ForumNameLine, p , 8 );		ForumNameLine[8] = '\0';
		setIdHandle( p );

	GET_LINE2												return( NO );
	if (	matchstr( PSP, "????????: %%/?%/%% ?%:%%:%%" ) != YES
	&&		matchstr( PSP, "???????? : %%/?%/%% ?%:%%:%%" ) != YES
	)														return( NO );
		set_hatsugen_date( );

	GET_LINE2												return( NO );

	if (	matchstr( PSP, "????????: " ) == YES
	||		matchstr( PSP, "???????? : " ) == YES
	) {
		ComNum = 0;
		p = SkipLeftMes( PSP );
		if ( *p == CR )										return( NO );
	} else {												return( NO );
	};
	/* ＩＤと題名のセット */
	setHyoudaiLine( p, YES );

	return( YES );
}

static	int		isBOADMes( )
{
	char	*p0, *p1;

	/* ボード名の行のチェック */
	if (	matchstr( PSP, "????????: " ) != YES
	&&		matchstr( PSP, "???????? : " ) != YES
	)														return( NO );

	p0= SkipLeftMes( PSP );
	p1= ForumNameLine;
	/* ボード名をコピーする */
	forever {
		p0= SkipEsc( p0 );
		if ( *p0 == '(' ) {
			p0= SkipEsc( p0+1 );
			if ( *p0 == '#' )					break;
		};
		if ( *p0 == CR )								return( NO );
		if ( p1 > ForumNameLine + 79 )					return( NO );
		*p1++= *p0++;
	};
	*p1= '\0';
	/* ボード名の続きの文字列のチェック */
				/*   123456789 123456789 */
	if ( matchstr( p0, "#%%%)  No.???%" ) != YES )		return( NO );
	/* ボード番号と発言番号を得る */
		p0= SkipEsc( p0 + 1 );			/* skip '#' */
		MesNum = atoi( p0 );
		p0= WaitChar( p0, '.' );
		if ( p0== NULL ) {
			puts( "プログラムのバグだなあ in isBOADMes" );	exit( 1 );
		};
		p0= SkipEsc( p0 + 1 );			/* skip '.' */
		SayNum = atoi( p0 );

	// 会議室名をセットする
	strcpy( KNL[MesNum], ForumNameLine );
	strcpy( ForumNameLineSub, ForumNameLine );

	/* 発言者の行のチェック */
	GET_LINE2												return( NO );
	if (	matchstr( PSP, "????????: $$$????? [????????]    " ) != YES
	&&		matchstr( PSP, "????????: $$$????? [????????????]    " ) != YES
			/* ↓ 1994.4.8 追加 */
	&&		matchstr( PSP, "????????: $$$????? [????????????????]    " ) !=YES
			/* YAGI-BBS の場合 */
	&&		matchstr( PSP, "???????? : $$$????? [????????????????]    " )!=YES
			/* DIGITAL-BBS のパターン */
	&&		matchstr( PSP, "???????? : $$$????? [??????????]    " ) != YES
	&&		matchstr( PSP, "???????? : $$$????? [????????]    " ) != YES
	&&		matchstr( PSP, "???????? : ---????? [????????]    " ) != YES
	)														return( NO);
		p0 = SkipLeftMes( PSP );
		setIdHandle( p0 );

	/* 発言日時の行のチェック */
	GET_LINE2												return( NO );
	if (	matchstr( PSP, "????????: %%/?%/%% ?%:%%:%%" ) != YES
	&&		matchstr( PSP, "???????? : %%/?%/%% ?%:%%:%%" ) != YES
	&&		matchstr( PSP, "???????? : **/**/** **:**:**" ) != YES
	)														return( NO );

	set_hatsugen_date( );

	/* 発言の標題の行のチェック */
	GET_LINE2												return( NO );
	if (	matchstr( PSP, "????????: Res [#%" ) == YES
	||		matchstr( PSP, "???????? : Res [#%" ) == YES
	||		matchstr( PSP, "????????: 返事[#%" ) == YES
	||		matchstr( PSP, "???????? : 返事[#%" ) == YES
	) {
		p0= WaitChar( PSP, '[' );
		p0= SkipEsc( p0 + 1 );				/* skip '[' */
		p0= SkipEsc( p0 + 1 );				/* skip '#' */
		ComNum = atoi( p0 );
		for ( ; isdigit( *p0 ) ; p0++ ) ;
		p0= SkipEsc( p0 );
		if ( strncmp( p0, "]:", 2 ) != 0 )					return( NO );
		p0 += 2;
	} else if	(	matchstr( PSP, "????????: " ) == YES
				||	matchstr( PSP, "???????? : " ) == YES
				) {
					ComNum = 0;
					p0 = SkipLeftMes( PSP );
					if ( *p0 == CR )						return( NO );
	} else {
															return( NO );
	};

	/* ＩＤと題名のセット */
	p0= SkipEsc( p0 );
	setHyoudaiLine( p0, YES );

	return( YES );
}

static	int		isBOADHyoudaiLine( char *ptr )
{
	if ( matchstr( ptr, "============================================================= %%/%%/%% ?%:%%:%%" ) != YES	)						return( NO );
	return( YES );
}

static	int		isRtBbsLIBFirstLine( char *ptr )
{
	if ( matchstr( ptr, "#%%% ???????? " ) != YES )			return( NO );
	if ( WaitStr( ptr, "検索中" ) == NULL )					return( NO );
	return( YES );
}

static	int		isRtBbsMesEnd( )
{
	// デリミタ
	/* 下の命令は <Nakatani> さんより教えていただいた */
	if	( *(int *)PSP == 0x0a0d0820 )			return( YES );

	/* 1993.12.12   4バイト未満に修正 */
	if ( PSL < 4 )											return( NO );

	if (	isBOADHyoudaiLine( PSP ) == YES
	||		isBOADHyoudaiLine( NSP ) == YES
	||		matchstr( PSP, "合計 % 個の新しいファイルがあります。" ) == YES
	||		matchstr( PSP, "合計 %% 個の新しいファイルがあります。" ) == YES
	||		matchstr( PSP, "合計 %%% 個の新しいファイルがあります。" ) == YES
	||		matchstr( PSP, "ファイルが存在しません。" ) == YES
	||		isRtBbsLIBFirstLine( PSP ) == YES
	||		matchstr( PSP, "削除中 ... 削除しました。" )==YES
	||		matchstr( PSP, "  ● 連続で読みます ●  （中断:^C）" )==YES
			/* ↓ 1994.4.8 追加 */
	||		matchstr( PSP, "[RET]:next L:oop P:rev A:s D:es R:es K:ill" )==YES
			/* DIGITAL-BBS の場合 */
	||		matchstr( PSP, "[RET]:次文章 L:再読 R:返信 P:前文章" )==YES
	||		matchstr( PSP, "DIRECTIVE :メッセージは以上です" )==YES
	||		matchstr( PSP, "メッセージ :メッセージは以上です。" )==YES
	)														return( YES );
	/* その他 */

	return( NO );
}

// RTBBS のログを検索する
// \source\rtbbs\all
static	int		Check1FileRtBbs( int ForumCopySw )
{
	SayDateCatlogFileStart= SayDateCatlogFileEnd= 0;
	*SayId= '\0';

	if ( ForumCopySw == YES )	strcpy( ForumName, rtBbsTmp.DirName );

	forever {
		CPDS = PSP;
		BStart				= pool_seek_ichi;
		saveSayData.GStart	= PoolGyou;
		/* 発言開始の行？ */
		if ( matchstr( PSP, "#%%% ???????? " ) == YES ) {
			if ( WaitStr( PSP, "検索中" ) != NULL ) {
				/* ForumName とHyoudaiLine をセットする */
				setBoadName();
			};
			GET_LINE2	break;
			continue;				/* 次の行をチェックする */
		} else if (	matchstr( PSP, "---- - ------------ ------ --- ------------------------------------------------" ) == YES
			||		matchstr( PSP, "---- - ------------ ----- ---- ------------------------------------------------" ) == YES
		) {
			/* ファイル・ボードの開始 */
			isLIBMes(  );
			continue;				/* 次の行をチェックする */
		} else if ( matchstr( NSP,
"============================================================= %%/%%/%% ?%:%%:%%" ) == YES	) {
			/* 現在の seek 位置を保存する */
			GET_LINE2	break;	/* PSP : ======日付の行   */
			GET_LINE2	break;	/* PSP : ボードの名前の行 */
			if (	matchstr( PSP, "????????: Private mail" ) == YES
			||		matchstr( PSP, "ボード名 : メールボックス" ) == YES
			) {
				if ( isMAILMes() != YES ) {
					continue;				/* 次の行をチェックする */
				};
			} else if ( isBOADMes( ) != YES ) {
				continue;				/* 次の行をチェックする */
			};
		} else {
			GET_LINE2	break;
			continue;
		};
		/* 発言の最後を見つける */
		do {
			CPDS = PSP;
			GET_LINE2	break;
		} while ( isRtBbsMesEnd() == NO );
		BEnd= pool_seek_ichi;
		Hyoudai = HyoudaiLine;
		checkSaveSayData( MesNum );
	};

	return( YES );
}

//	###########################################################################
//	##### RT-BBS のログを整理する ####### ここまで ############################
//	###########################################################################


// ファイル名＋拡張子を見て 削除するかどうかを判断する
static	int		isDeleteOldFile( const char *name )
{
	int		date;
	char	file[ 16 ] , *p;

	if ( ForceDeleteOldFileSw == YES )				return( YES );

	strcpy( file , name );
	p = last_comma( file );
	if (	strlen( name ) != 12
	||		*ToDay == '\0'
	||		isFAPXfile( name ) == NO						// FAPXのファイル ?
	||		(		strcmp( p , ".LOG" ) != 0				// 拡張子の指定
			&&		strcmp( p , ".RES" ) != 0
			&&		strcmp( p , ".UP" ) != 0
			&&		strcmp( p , ".EML" ) != 0
			&&		strcmp( p , ".NPB" ) != 0
			)
	)												return( NO );

	/* ファイルの年月日のチェック */
	if ( FapxLogMode == 2 ) {				/* 圧縮あり */
		/* 月の設定 */
		date = (*file) & 0x0f;		if ( ! isdigit( *file ) ) date += 9;
		/* 日の設定 */
		file[ 3 ] = '\0';			date = date * 100 + atoi( file + 1 );
		/* 年の設定 */
		strcpy( file , ToDay );	file[ 2 ] = '\0';
		date = atoi( file ) * 10000 + date;
		/* CATLOGの内部形式に変更 */
		date = date * 100;
		/* 文字列に変更 */
		sprintf( file , "%-08d" , date );
	};
	file[ 8 ] = '\0';
	if ( strcmp( file , ToDay ) >= 0 )				return( NO );

	return( YES );
}

static	int		check_start_line()
{
	if ( PSL == 0 )											return( 0 );

	/* ﾌｫｰﾗﾑの入口 */
	/************************************************
	1:お知らせ            2:掲示板      3:電子会議
	*************************************************/
	if ( isMesInputLine(PSP,NSP) == YES ) 					return( 1 );
	/* ﾌｫｰﾗﾑの会議室の名前 */
	if ( isMesForumNameLine(PSP) == YES )					return( 2 );
	/* 発言の表題の行 */
	if ( isMesHyoudaiLine(PSP,NSP)==YES )					return( 3 );
	/* Home Party の入口 */
	IfMatchStrYes("ID (改行のみ：自分のHP)")				return( 4 );
	/* MAIL */
	if ( isMailFirstLine(PSP,NSP) == YES )					return( 5 );
	/* BILL */
	if ( isBillFirstLine(PSP) == YES )						return( 6 );
	/* Home Party の入口 */
	if ( isHpHyoudaiLine(PSP) == YES )						return( 7 );
	/* LIB の入口 */
	if ( isLIBFirstLine(PSP) == YES )						return( 8 );
	/* PATIOの入口 */
	IfMatchStrYes("ID (改行のみ：自分のパティオ)")			return( 9 );
	/* クリッピングサービスの行 */
	if ( isCLIPFirstLine( PSP ) == YES )					return( 10 );
	if ( isCLIPLine( PSP ) == YES )							return( 10 );

	return( 0 );
}

static	void	next_str_print()
{
	char	*p, ch;

	p= NSP + NSL ;
	ch= *p;
	*p= '\0';
	PrintMessage( "\n" );
	PrintMessage( NSP );
	*p= ch;
}

/* - Fxxxx から会議室番号を取り出す                                     */
/* - FTOWNS1  MES(18):通信ソフトについて(３) 92/04/25 -                 */
static	int		get_mes_num_from_forum_name_line( char *str )
{
	char	forumName[ 10 ];

	if ( matchstr( str, "- F$" ) == NO )						return( 0 );
	str= CopyAlnum8( forumName, str + 2 );
					//    123456
	if ( matchstr( str, "  MES(?%):" ) == NO )					return( 0 );
	return( atoi( str + 6 ) );
}

/* - Fxxxx からフォーラム名を取り出す                                   */
/* - FTOWNS1  MES(18):通信ソフトについて(３) 92/04/25 -                 */
static	void	get_forum_name( char *str , char *forumName )
{
	*forumName = '\0';
	if ( matchstr( str, "−会議室?%" ) != YES ) {
		CopyAlnum8( forumName, str + 2 );
	};
}

static	void	get_mes_now_number( char *str , char *now )
{
	char	*p1;

	if ( *(str+3) == '/' ) {
		p1 = str + 4;	/* xxx/xxx の行 */
		*now++ = *p1++;	*now++ = *p1++;	*now++ = *p1++;
	} else if ( *( str + 5 ) == '/' ) {
		p1 = str + 6;	/* xxxxx/xxxxx の行 */
		*now++ = *p1++;	*now++ = *p1++;	*now++ = *p1++;
		*now++ = *p1++;	*now++ = *p1++;
	};
	*now = '\0';
}

/* result :
	YES	発言の終了である
	NO	発言の終了ではない
*/
static	int		is_1_say_end( char *now , int mode )
{
	int		d;
	int		m1,m2;
	char	sub[ 16 ];

	if ( PSL == 0 )												return( NO );

	if ( isMesInputLine(PSP,NSP) == YES )						return( YES );

	if ( isMesHyoudaiLine(PSP,NSP) == YES ) {
		if ( mode == MES_MODE )									return( YES );
		/* PSP から基数を得る */
		get_mes_now_number( PSP , sub );
		/* 一致する場合は終了 */
		if ( strcmp( now , sub ) == 0 )							return( YES );
		/************************************/
		/* 引用部分であるので発言を修正する */
		/************************************/
		/* 下の範囲は引用ではないとする */
		/* 会議室番号のチェック */
		if ( atoi( MesNumberLine + 1 ) == atoi( NSP + 1 ) ) {
			/************************/
			/* 会議室番号が同じ場合 */
			/************************/
			m1 = atoi( now );	m2 = atoi( sub );
			/* 以下の if 文を追加 1993.10.12 */
			if ( m1 < m2 && m2 <= m1 + 5 ) {
				// now を更新して終了 引用発言とはみなさない
				strcpy( now , sub );							return( YES );
			};
			sprintf( YesNoMes, "\n<%s>の\n%s\n%s\nで引用部分を見つけました。",
				FileName ,
				HyoudaiLine ,		/* 発言の表題の行 */
				MesNumberLine		/* 会議室番号の行 */
			);
			PrintMessage( YesNoMes );
			if ( m1 < m2 ) {
				/* 新しい基数の方が大きい場合のみ、たずねる */
				present_str_print();
				next_str_print();
				sprintf(YesNoMes, "\n発言の基数＝（旧）%s → （新）%s ですが、"
					, now , sub
				);
				PrintMessage( YesNoMes );
				if ( QuoteAllSaySw == NO ) {
					if ( WithoutMESSaySw == YES ) {
						sprintf(YesNoMes,
							"発言の基数を（新＝%s）に変更します。", sub
						);
						PrintMessage( YesNoMes );
						strcpy( now , sub );
						// 修正しないが、発言の区切りとはする
																return( YES );
					};
					if ( get_yesno( "引用として処理します" ) == NO ) {
						sprintf( YesNoMes, 
							"\n発言の基数を（新＝%s）に変更します",
							sub
						);
						if ( get_yesno( YesNoMes ) == YES) {
							strcpy( now, sub );
						};
						// 修正しないが、発言の区切りとはする
																return( YES );
					};
				} else {
					PrintMessage( "オプション・スイッチで強制的に、");
				};
			};
			PrintMessage("修正します。");
		} else {
			/**************************/
			/* 会議室番号が異なる場合 */
			/**************************/
			; /* 何もしない → 引用として扱う */
		};
		InyouSw= YES;
		return( NO );
	};

	/****************/
	/* - Fxxxxxの行 */
	/****************/
	if ( isMesForumNameLine(PSP) == YES ) {
		d = get_mes_num_from_forum_name_line( PSP );
		present_str_copy( KNL[ d ] );

		if ( mode == MES_MODE )						return( YES );
		/* ﾌｫｰﾗﾑ名がある場合  - Fxxxxの場合 */
		get_forum_name( PSP , sub );
		/* 一致する場合は終了 */
		if ( strcmp( ForumName , sub ) == 0 )		return( YES );
		/* 1993.11.28 ２つのフォーラム名に対応 */
		if (	*ForumName2 != '\0'
		&&		strcmp( ForumName2, sub)== 0
		)											return( YES);
		/* 一致しない場合 */
		if ( mode == FORUM_MODE )					return( YES );

		/************************************/
		/* 引用部分であるので発言を修正する */
		/************************************/
		sprintf( YesNoMes, "\n<%s>の\n%s\n%s\nで引用部分を見つけました。",
			FileName ,
			HyoudaiLine ,		/* 発言の表題の行 */
			MesNumberLine		/* 会議室番号の行 */
		);
		PrintMessage( YesNoMes );
		present_str_print();
		PrintMessage("修正します。");
		InyouSw= YES;
		return( NO );	/* 無視する */
	};

	if ( isMesEnd() == YES )					return( YES );

	if ( check_start_line() != 0 )				return( YES );

	if ( MesNum == PATIO ) {
		if ( isPATIOEnd() == YES )				return( YES );
	};

	return( NO );
}

static	void	initial_DL_name()
{
	int	i;

	for ( i=0 ; i<MAX_KAIGISHITSU ; i++ )	*DL_name[ i ] = '\0';
}

static	void	initial_kaigishitsu_name()
{
	int	i;

	for ( i=0 ; i<MAX_KAIGISHITSU ; i++ )	*KNL[ i ] = '\0';
}

static	void	checkSkipUselessLine()	/* 必要のない行を読み飛ばす */
{
	int		lineNum;

	/* 番号　発言 (未読) 　最新　　会議室名 の行を探す */
	while ( check_start_line() ==  0 ) {
		/*         123456789 123456789 123456789 123456 */
		IfMatchStrYes("番号　発言 (未読) 　最新　　会議室名") {
			/* 会議室の一覧を KNL に入れる */
			initial_kaigishitsu_name();	/* 初期化 */
			forever {
				GET_LINE;					/* 先読み */
				checkSetLibNumber();
				IfMatchStrYes("＞")	break;	/* 行頭の｢＞｣で終了 */
				lineNum = atoi( PSP );
				if ( lineNum == 0 )	break;	/* 終了 */
				if ( lineNum > 20 )	break;	/* 終了 */
				present_str_copy( KNL[ lineNum ] );
			};
			/* 会議室の状況をファイルに書き出す */
//			check_save_kaigishitsu_line();
		};
		/*         123456789 123456789 123456789 123456789  */
		IfMatchStrYes("番号　総数　登録済　最新　　ライブラリ名") {
			/* ＤＬの一覧を DL_name に入れる */
			initial_DL_name();				/* 初期化 */
			forever {
				GET_LINE;					/* 先読み */
				checkSetLibNumber();
				IfMatchStrYes("＞")	break;	/* 行頭の｢＞｣で終了 */
				lineNum = atoi( PSP );
				if ( lineNum == 0 )	break;	/* 終了 */
				if ( lineNum > 20 )	break;	/* 終了 */
				present_str_copy( DL_name[ lineNum ] );
			};
			/* ＤＬの状況をファイルに書き出す */
//			check_save_DL_line();
		};
		if ( isLIBLine() == YES )	break;
		GET_LINE;		/* 先読み */
		checkSetLibNumber();
	};
}

static	void	checkBill()
{
	BStart				= pool_seek_ichi;
	saveSayData.GStart	= PoolGyou;
	/*******************************/
	/* 3か月分の課金データをストア */
	/*******************************/
	SayNum = CheckBillGetSayNum();							/* 発言番号 */

	if ( check_start_line() ==  0 ) {
		// BILL の最後まで読み飛ばす
		while( isBILLEnd() == NO ) {
			GET_LINE2 break;		checkSetLibNumber();	/* 先読み */
		};
	};
	BEnd= pool_seek_ichi;
	if ( WithoutBILLSaySw == NO ) {
		strcpy( ForumName , "BILL" );					/* フォーラム名 */
		ComNum = 0;										/* コメント元番号 */
		*SayId = '\0';									/* 発言者のＩＤ */
		strcpy( ForumNameLine , "- BILL:NIFTYの利用料金情報です。");
		*ForumNameLineSub = *Handle= '\0';
		MesNum = BILL;									/* 会議室番号 */
		Hyoudai = NULL;
		checkSaveSayData( BILL );
	};
	return ;
}

/*****************************************************/
/* last_str に LIB 番号が入っている                  */
/* next_str には、＞1 が入っていることをチェックする */
/*****************************************************/
static	int		isLibNumDir()
{
	int	len;
	char	dir[ 20 ] , *p;

	if ( NSL > 19 )				return( NO );
	if ( NSL < 3 )				return( NO );
	if ( strncmp( NSP , "＞" , 2 ) != 0 )	return( NO );

	len = NSL - 2;
	p = NSP + 2;
	while ( isspace( *p ) ) {	p++;	len--;	};

	strncpy( dir , p , len );

	if ( strncmp( dir , "1" , len ) == 0 )		return( YES );
	if ( strncmp( dir , "１" , len ) == 0 )		return( YES );
	if ( strncmp( dir , "ＤＩＲ" , len ) == 0 )	return( YES );
	if ( strncmp( dir , "ｄｉｒ" , len ) == 0 )	return( YES );

	/* 文字列を小文字にする */
	p = dir;
	while ( len>0 ) {
		*p++ = toupper( *p );
		len--;
	};
	*p = '\0';
	if ( strcmp( dir , "DIR" ) == 0 )		return( YES );

	return( NO );
}

static	int		check_lib_num()
{
	int	len,lib_num;
	char	dir[ 20 ] , *p;

	if(strncmp(LSP,"−ダウンロード終了−",20) == 0)	return( YES );

	lib_num = 0;
	if ( isLibNumDir() == NO )					return( NO );

	if ( LSL > 19 )							return( NO );
	if ( LSL < 3 )							return( NO );
	if ( strncmp( LSP , "＞" , 2 ) != 0 )	return( NO );

	p = LSP + 2;	len = LSL - 2;
	while ( isspace( *p ) ) {	p++;	len--;	};
	strncpy( dir , p , len );
	dir [ len ] = '\0';

	/* 文字列を大文字にする */
	p = dir;	while ( len > 0 ) {	*p++ = toupper( *p );	len--;	};
	p = dir;
	if ( strncmp( dir, "LIB", 3) == 0 ) {		p += 3;
	} else if ( strncmp( dir, "LX ", 3) == 0) {	p += 2;
	};

	/* 仮に LIB 番号を lib_num に入れる */
	lib_num = atoi( p );	if ( lib_num == 0 )		return( NO );

	/* 0でなければ、新しい LIB 番号とする */
	lib_number = lib_num;
	return( YES );
}

static	void	checkLibMain( const char *forum__name )
{
	char	*p1, *p2, *pSub;
	long	GStartSub;

	forever {
		check_lib_num();
		GET_LINE;						/* 先読み */
		checkSetLibNumber();
		checkSkipUselessLine();			/* 必要のない行を読み飛ばす */
		if ( isLIBLine() == YES )				break;
		if ( isLIBFirstLine(PSP) == NO )		return;
	};

	strcpy( ForumName , forum__name );
	SayNum = lib_number;						/* 発言番号 */
	checkSetSayDate( LIB, PSP );				/* 発言の日付 */
	ComNum = 0;									/* コメント元番号 */
	*SayId = '\0';								/* 発言者のＩＤ */
	/* 1994.2.13 追加 ＤＬのタイトルを入れる */
	p1= DL_name[ lib_number ];
	if ( *p1 == '\0' ) {	*ForumNameLineSub = '\0';
	} else {				strcpy( ForumNameLineSub, p1 );
	};

	MesNum = LIB;					/* 会議室番号 */

	/* ID の下には LIB を作らない */
	if ( WithoutLIBSaySw == YES )	return;

	BStart				= GStartSub= pool_seek_ichi;
	saveSayData.GStart	= PoolGyou;
	CPDS = PSP;
	forever {
		if ( isLIBLine() == NO ) {
			IfMatchStrYes( "番号 (改行で次頁)" ) {	/* 2行 読み飛ばす */
				GET_LINE2 break;		/* 先読み */
				checkSetLibNumber();
				GET_LINE2 break;		/* 先読み */
				checkSetLibNumber();
				continue;
			} else {											break;
			};
		};
		GET_LINE2 break;		/* 先読み */
		checkSetLibNumber();
	};
	BEnd= pool_seek_ichi;
	*SayId= *Handle= '\0';
	Hyoudai= NULL;
	checkSaveSayData( MesNum );
	checkSkipUselessLine();	/* 必要のない行を読み飛ばす */

	/* CPDS から PSP までを調べる */
	p1= pSub= CPDS;
	p2= PSP;		/* 保存用 */
	while ( p1 < p2 ) {
		if ( isSearchId( p1 + 6 ) == NO ) {
			// 次の行
			while ( ( p1 < p2 ) && ( *p1 != 0x0a ) ) p1++;
			p1++;									/* next char */
			continue;
		};
		CPDS = p1;
		checkSetSayDate( LIB, p1 );				/* 発言の日付 */
		while ( ( p1 < p2 ) && ( *p1 != 0x0a ) ) p1++;
		p1++;										/* next char */
		PSP = p1;
		MesNum = COLLECT_LIB;
		BStart= GStartSub + CPDS - pSub;
		BEnd  = GStartSub + PSP  - pSub;
		checkSaveSayData( COLLECT_LIB );
	};
	PSP = p2;		/* 保存用 */
	*SayId = '\0';
}

static	void	skip_1_say( char *now , int mode )
{
	forever {
		if (	checkCheckEnd() == YES
		&&		is_1_say_end( now , mode ) == YES
		) {
				break;
		};
			/* 123456789 123456789 123456789 */
		IfMatchStrYes("続き（改行で表示　S:次の発言）") {
			if (	NSL == 2
			&&	strncmp( NSP , "＞" , 2 ) == 0
			) {
				/* 2行 読み飛ばす */
				GET_LINE2 break;	/* 先読み */
				GET_LINE2 break;	/* 先読み */
				continue;
			};
		/**************************/
		/* ブラウズモードへの対応 */
		/*               1993.3.1 */
		/**************************/
		} else IfMatchStrYes("続き (改行で表示　S:次タイトル)" ) {
			if (	NSL == 2
			&&	strncmp( NSP , "＞" , 2 ) == 0
			) {
				/* 2行 読み飛ばす */
				GET_LINE2 break;	/* 先読み */
				GET_LINE2 break;	/* 先読み */
				continue;
			};
		};
		GET_LINE2 break;	/* 先読み */
		checkSetLibNumber();
	};
}

/****************************************************************
>- FTOWNS1  MES(18):通信ソフトについて(３) 92/04/25 -
> 123456789 123456789 123456789 123456789 123456789
>001/999   NAA02244  飛雪              初めての発言
>(18)   92/01/24 18:40
*****************************************************************/
static	void	checkSaveStartMes( int mesNum )
{
	if ( HyoudaiLine[ 3 ] == '/' ) {
		CopyAlnum8( SayId, HyoudaiLine + 10 );
		strncpy( Handle, HyoudaiLine + 20, 16 );
		Hyoudai = HyoudaiLine + 38;
	} else {
		CopyAlnum8( SayId, HyoudaiLine + 12 );
		strncpy( Handle, HyoudaiLine + 22, 16 );
		Hyoudai = HyoudaiLine + 39;
	};
	Handle[ 16 ]= '\0';
	SayNum = atoi( HyoudaiLine );							/* 発言番号 */
	checkSetSayDate( MES, MesNumberLine );					/* 日付 */
	// コメント元番号
	if (	strlen(  MesNumberLine ) > 21
	&&		isdigit( MesNumberLine[23] )
	) {			ComNum = atoi( MesNumberLine + 23 );
	} else {	ComNum = 0;
	};
	checkSaveSayData( mesNum );
}

static	int		check_SearchStartSay( char *str , int mail_sw )
{
	char	sub[ 8 ] , *p1 , *p2;

	if ( SearchSayStartDateSw == NO )	return( YES );
	p1 = sub;
	if ( mail_sw == YES ) {
		p2 = SearchSayStartDate + 2;
	} else {
		p2 = SearchSayStartDate;
		*p1++ = *str++;	*p1++ = *str++;		/* YY */
		str++;	/* '/' */
	};
	*p1++ = *str++;	*p1++ = *str++;			/* MM */
	str++;	/* '/' */
	*p1++ = *str++;	*p1++ = *str++;			/* DD */
	*p1 = '\0';
	if ( strcmp( p2 , sub ) <= 0 )	return( YES );
	return( NO );
}

static	int		check_SearchEndSay( char *str , int mail_sw )
{
	char	sub[ 8 ] , *p1 , *p2;

	if ( SearchSayEndDateSw == NO )	return( YES );
	p1 = sub;
	if ( mail_sw == YES ) {
		p2 = SearchSayEndDate + 2;
	} else {
		p2 = SearchSayEndDate;
		*p1++ = *str++;	*p1++ = *str++;		/* YY */
		str++;	/* '/' */
	};
	*p1++ = *str++;	*p1++ = *str++;			/* MM */
	str++;	/* '/' */
	*p1++ = *str++;	*p1++ = *str++;			/* DD */
	*p1 = '\0';
	if ( strcmp( sub , p2 ) <= 0 )	return( YES );
	return( NO );
}

static	int	check_SearchSayDate( char *str , int mail_sw )
{
	if ( check_SearchStartSay( str , mail_sw ) == NO )	return( NO );
	if ( check_SearchEndSay( str , mail_sw )   == NO )	return( NO );
	return( YES );
}

static	void	save_1_say( const char *forum__name , char *now , int mode )
{
	int		i;
	char	*p1 , *p2;

	/******************/
	/* 手動通信に対応 */
	/*       1993.3.3 */
	/******************/
	get_mes_now_number( HyoudaiLine , now );	/* sub.c */

	/**************************/
	/* ブラウズモードへの対応 */
	/*               1993.3.1 */
	/**************************/
			/*  123456789 123456789 123456789 123456 */
	IfMatchStrYes("読む (1:表示　改行のみ：次タイトル)" ) {
		GET_LINE;	/* PresentStr を読み飛ばす */
		IfMatchStrYes( "＞" ) {
			p1 = PSP + 2;
			p1 = skip_space( p1 );		/* 漢字も認識する sub.c */
			if (	*p1 == 0x0d
			||	(	*p1 != '1'
				&&	( strncmp( "１" , p1 , 2 ) != 0 )
				)
			) {
				skip_1_say( now , mode );		return;
			};
		} else {
			error_return("ブラウズモードの発言なのに「＞」がみつかりません");
		};
		GET_LINE;		/* ブラウズモードでの発言の開始 */
	};

	/* フォーラム名 */
	strcpy( ForumName , forum__name );

	CPDS = PSP;

	if (	WithoutMESSaySw == YES
	||		check_SearchSayDate( MesNumberLine + 7 , NO ) == NO
	) {
		skip_1_say( now , mode );		return;
	};

	/****************************/
	/* 削除した発言は登録しない */
	/*              1992.8.26   */
	/****************************/
	if ( DeleteDeletedSaySw == YES ) {
		if ( HyoudaiLine[ 3 ] == '/' ) {
			p1 = HyoudaiLine + 10;		p2 = HyoudaiLine + 38;
		} else {
			p1 = HyoudaiLine + 12;		p2 = HyoudaiLine + 39;
		};
		if ( *p1 == '*' || strncmp( p2 , "発言者削除" , 10 ) == 0 ) {
			skip_1_say( now , mode );		return;
		};
	};

	/******************************************/
	/* 先ず、この発言を CATLOG.TMP に書き出す */
	/******************************************/

	/* 会議室を表す行をセット */
	i = atoi( MesNumberLine + 1 );	/* 会議室番号 */
	if ( 0<i && i<21 ) {
		if ( *KNL[ i ] != '\0' ) {
			strcpy(	ForumNameLineSub , KNL[ i ] );
		};
	} else {
			*ForumNameLineSub = '\0';
	};

	*SayId = '\0';

	/* 会議室番号 */
	MesNum= atoi( MesNumberLine + 1 );
	forever {
		if (	checkCheckEnd() == YES
		&&		is_1_say_end( now , mode ) == YES
		) {
				break;
		};
			/* 123456789 123456789 123456789 */
		IfMatchStrYes("続き（改行で表示　S:次の発言）") {
			if (	NSL == 2
			&&	strncmp( NSP , "＞" , 2 ) == 0
			) {
				/* 2行 読み飛ばす */
				GET_LINE2 break;	/* 先読み */
				GET_LINE2 break;	/* 先読み */
				continue;
			};
		/**************************/
		/* ブラウズモードへの対応 */
		/*               1993.3.1 */
		/**************************/
		} else IfMatchStrYes("続き (改行で表示　S:次タイトル)" ) {
			if (	NSL == 2
			&&	strncmp( NSP , "＞" , 2 ) == 0
			) {
				/* 2行 読み飛ばす */
				GET_LINE2 break;	/* 先読み */
				GET_LINE2 break;	/* 先読み */
				continue;
			};
		};
		GET_LINE2 break;	/* 先読み */
		checkSetLibNumber();
	};

	BEnd= pool_seek_ichi;
	checkSaveStartMes( MesNum );

	/****************/
	/* ＩＤで収集？ */
	/****************/
	if ( HyoudaiLine[ 3 ] == '/' ) {	p1 = HyoudaiLine + 10;
	} else {							p1 = HyoudaiLine + 12;
	};
	if ( isSearchId( p1 ) == YES ) {		/* sub.c */
		checkSaveStartMes( COLLECT_ID );
	};
}

/*********************************************************************/
/* - Fxxxx から始まる場合                                            */
/* - FTOWNS1  MES(18):通信ソフトについて(３) 92/04/25 -              */
/*     ﾌｫｰﾗﾑ名は- Fxxxx から取る                                     */
/*     - Fxxxx  で終了                                               */
/*                                                                   */
/*     同じフォーラムの中の発言を処理する                            */
/*     フォーラムが異なれば出る。                                    */
/*                                                                   */
/*********************************************************************/
static	void
check_forum_name_mode_loop( const char *forum__name, const int mode )
{
	int		d;
	char	sub[ 24 ] , now[ 8 ];

	if ( isMesHyoudaiLine(PSP,NSP) == NO ) {
		if ( PSP == NULL )	return;
		PrintMessage( "\n表題の行でないといけないのに、"
						"そうなっていないぞ〜〜。" );
		PrintMessage( "\nあれ〜〜ＣＡＴＬＯＧのバグだぞ〜〜↓");
		present_str_print();
	};

	*now = '\0';
	get_mes_now_number( PSP , now );	/* sub.c */

	forever {
		BStart				= pool_seek_ichi;
		saveSayData.GStart	= PoolGyou;
		present_str_copy( HyoudaiLine );

		GET_LINE;			/* 先読み : 会議室番号の行 */
		checkSetLibNumber();
		present_str_copy( MesNumberLine );

		GET_LINE;			/* 先読み : 発言開始の行 */
		checkSetLibNumber();

		/**************/
		/* 発言の登録 */
		/**************/
		save_1_say( forum__name , now , mode );

		checkSkipUselessLine();		/* 必要のない行を読み飛ばす */
		while( isLIBFirstLine(PSP)==YES ) checkLibMain( forum__name );

		/* 次の発言に対する処理 */
		if ( isMesHyoudaiLine(PSP,NSP) == YES ) {
			/* 次の発言   */
			/* 何もしない */
		} else if ( isMesForumNameLine(PSP) == YES ) {
			/* - FRAV の行 */
			if ( mode == FORUM_MODE ) {
				/* ﾌｫｰﾗﾑ名が異なれば終了 */
				get_forum_name( PSP , sub );
				if (	strcmp( forum__name , sub ) != 0
				/* 1993.11.28 ２つのフォーラム名に対応 */
				&&		(	*ForumName2 != '\0'
						&&	strcmp( ForumName2, sub) != 0
						)
				)												return;
			};
			d = get_mes_num_from_forum_name_line( PSP );
			present_str_copy( KNL[ d ] );
			present_str_copy( ForumNameLineSub );
			GET_LINE;		/* 先読み : 発言の表題の行 */
			checkSetLibNumber();
			checkSkipUselessLine();	/* 必要のない行 */
			if ( isMesHyoudaiLine(PSP,NSP) != YES ) return;
			/********************/
			/* now を書き換える */
			/********************/
			get_mes_now_number( PSP , now );
		} else {
			return;
		};
	};
}

/***********************************************************/
/* ＜リアルタイムAV通信フォーラム＞    FRAV                */
/* 1:お知らせ            2:掲示板      3:電子会議          */
/* 4:データライブラリ    5:会員情報    6:リアルタイム会議  */
/* 7:SYSOP 宛メール      8:オプション  E:終了              */
/***********************************************************/
static	int		check_forum_mode_end()
{
	if ( isMesInputLine(PSP,NSP) == YES )		return( YES );
	IfMatchStrYes("ID (改行のみ：自分のHP)")	return( YES );	/* HP */
	if ( isHpHyoudaiLine(PSP) == YES )			return( YES );	/* HP */
	IfMatchStrYes("ID (改行のみ：自分のパティオ)")	return( YES );	/* PATIO */
	if ( isMailFirstLine(PSP,NSP) == YES )		return( YES );	/* MAIL */
	if ( isBillFirstLine(PSP) == YES )			return( YES );	/* BILL */
	if ( isLIBLine() == YES )					return( YES );	/* LIB 番号 */
	return( NO );
}

static	int		get_forum_name_last_str( )
{
	int		sw;
	char	*p1, *p2;

	/* 1993.11.28 ２つのフォーラム名に対応 */
	*ForumName2= '\0';

	if ( matchstr( LSP, "＜練習・質問コーナー＞" ) == YES ) {
		strcpy( ForumName , "BEGIN" );
		return( YES );
	};

	if ( isMtlinkInputLine( PSP, NSP ) == YES ) {
		strcpy( ForumNameLine, "＜メーテル広場＞    HIROBA" );
		strcpy( ForumName , "HIROBA" );
		return( YES );
	};

	p1 = LSP;	sw = NO;
	while ( *p1 ) {
		if(p1[0]==' ' && p1[1]==' ' && p1[2]==' ' && p1[3]==' ' ) {
			sw = YES;	break;
		};
		p1++;
	};
	if ( sw == NO )										return( NO );

	p1 += 4;	p2= ForumName;
	while ( isalnum( *p1 ) ) *p2++ = *p1++;
	*p2= '\0';

	/* 1993.11.28 ２つのフォーラム名に対応 */
	if ( *p1 == ' ' ) {
		p1 += 4;
		p2= ForumName2;
		while ( isalnum( *p1 ) ) *p2++ = *p1++;
		*p2= '\0';
	};

	return( YES );
}

static	void	checkForumMode()
{
	int		d;
	char	sub[ 20 ];

	initial_kaigishitsu_name();
	*ForumName= *ForumName2= *ForumNameLine= *ForumNameLineSub= '\0';

	/* ＜リアルタイムAV通信フォーラム＞    FRAV */
	/* の行をコピー                           */
	strncpy( ForumNameLine, LSP, LSL);	ForumNameLine[ LSL]= '\0';
	*ForumNameLineSub = '\0';

	if ( get_forum_name_last_str( ) == NO ) {
		/* 前の行にフォーラム名がない */
		strcpy( ForumName , "BEGIN" );
	};

	forever {
		GET_LINE;	/* 先読み:不用の行 */
		checkSetLibNumber();
		checkSkipUselessLine();	/* 必要のない行を読み飛ばす */
		while( isLIBFirstLine(PSP) == YES ) checkLibMain( ForumName );

		while ( isMesForumNameLine(PSP) == YES ) {

			/*******************************************/
			/* １つのﾌｫｰﾗﾑに２つの名前がある場合の対応 */
			/*                                1993.3.3 */
			/*******************************************/
			/* -Fxxxxx からフォーラム名を得る */
			get_forum_name( PSP , sub);
			/* 1993.11.28 修正 */
			if (	*ForumName2 != '\0'
			&&		strcmp( sub, ForumName2)== 0
			) {
				/* 付け刃の対応だなあ */
				/* strcpy( ForumName, ForumName2); */
			};

			d = get_mes_num_from_forum_name_line( PSP );
			present_str_copy( KNL[ d ] );
			present_str_copy( ForumNameLineSub );
			GET_LINE;	/* 先読み */
			checkSetLibNumber();
			checkSkipUselessLine();	/* 必要のない行を読み飛ばす */
			while( isLIBFirstLine(PSP) == YES ) checkLibMain( ForumName );
			/******************************************/
			/* フォーラム関係以外の行があると終了する */
			/******************************************/
			if ( check_forum_mode_end() == YES )		return;
		};

		/******************************************/
		/* フォーラム関係以外の行があると終了する */
		/*                              1992.9.15 */
		/******************************************/
		if ( check_forum_mode_end() == YES )		return;

		check_forum_name_mode_loop( ForumName , FORUM_IN_MODE );

		checkSkipUselessLine();	/* 必要のない行を読み飛ばす */
		while (	isLIBFirstLine(PSP) ==YES	) checkLibMain( ForumName );

		/******************************************/
		/* フォーラム関係以外の行があると終了する */
		/*                              1992.9.15 */
		/******************************************/
		if ( check_forum_mode_end() == YES )		return;
	};
}

/*******************************************/
/* ここからが forum_name_mode の本当の入口 */
/*******************************************/
static	void	checkForumNameMode()
{
	initial_kaigishitsu_name();
	*ForumName= *ForumName2= *ForumNameLine= *ForumNameLineSub= '\0';

	present_str_copy( ForumNameLineSub );
	get_forum_name( PSP , ForumName );
	sprintf( ForumNameLine, "＜%s＞", ForumName );

	GET_LINE;				/* 表題の行 */
	checkSetLibNumber();
	checkSkipUselessLine();			/* 必要のない行を読み飛ばす */
	if ( isMesHyoudaiLine(PSP,NSP) != YES )						return;
	check_forum_name_mode_loop( ForumName , FORUM_MODE );
}

/**************************************************/
/* xxx/xxx から始まる場合                         */
/*                                                */
/* 001/999   NAA02244  飛雪              お知らせ */
/* (00)   92/01/02 03:04                          */
/**************************************************/
static	void	checkHyoudaiLineMode( char *dir_name )
{
	char	now[ 8 ];

	initial_kaigishitsu_name();

	get_mes_now_number( PSP , now );				/* now の設定 */

	strcpy( ForumName, "UN_KNOWN" );
	strcpy( ForumNameLine, "- UN_KNOWN:フォーラム名が不明の発言です。");
	*ForumNameLineSub = '\0';

	forever {
		/* 発言の表題の行 */
		BStart				= pool_seek_ichi;
		saveSayData.GStart	= PoolGyou;
		present_str_copy( HyoudaiLine );
		GET_LINE;			/* 会議室番号の行 */
		checkSetLibNumber();
		present_str_copy( MesNumberLine );
		GET_LINE;			/* 先読み : 発言開始の行 */
		checkSetLibNumber();
		save_1_say( dir_name , now , MES_MODE );
		checkSkipUselessLine();	/* 必要のない行を読み飛ばす */
		if ( isMesHyoudaiLine(PSP,NSP) != YES )	return;
	};
}

/**********************************************************************
>ID (改行のみ：自分のHP)
>：NAA02244
>パスワード
>：
>HP>READ NEW
>          1         2         3         4         5         6
> 123456789 123456789 123456789 123456789 123456789 123456789 123456789
>001  [92/05/04 16:00]  NAA02244      オープンしました
***********************************************************************/
static	void	checkHpLoop( const char *id_name )
{
	int		d, lineNumber;

	d = 0;
/*
	PrintMessage( "\n" );
	PrintMessage( ForumNameLine );
*/
	while ( isHpHyoudaiLine(PSP) == YES ) {
		present_str_copy( HyoudaiLine );
		Hyoudai = HyoudaiLine + 37;
		BStart				= pool_seek_ichi;
		saveSayData.GStart	= PoolGyou;
		CPDS = PSP;
		d = PSL;
		checkSetSayDate( HP, CPDS );				/* 日付 */
		strcpy( ForumName , id_name );
		SayNum = atoi( PSP );						/* 発言番号 */
		ComNum = 0;									/* コメント元番号 */
		getComNum( PSP, PSL, 0 );
		//	*ForumNameLineSub= '\0';				// 1994.2.13 削除

		if (	WithoutHPSaySw == YES
		||		check_SearchSayDate( PSP + 6 , NO ) == NO
		) {
			GET_LINE2	break;		checkSetLibNumber();
			checkSkipUselessLine();	continue;
		};

		/******************************************/
		/* 先ず、この発言を CATLOG.TMP に書き出す */
		/******************************************/
		*SayId = '\0';
		MesNum = HP;								/* 会議室番号 */
		GET_LINE2 ;									/* 次の行 break はしない */
		checkSetLibNumber();
		lineNumber= 0;
		while (	isHpHyoudaiLine(PSP) != YES ) {
			lineNumber++;
			if (	lineNumber < 4
			&&		ComNum == 0
			)	getComNum( PSP, PSL, 0 );
			if ( checkCheckEnd() == YES ) break;
			GET_LINE2	break;		checkSetLibNumber();
		};
		BEnd= pool_seek_ichi;
		if ( WithoutHPSaySw == NO ) {
			*Handle= '\0';
			CopyAlnum8( SayId,  CPDS + 23 );
			checkSaveSayData( MesNum );
			/****************/
			/* ＩＤで収集？ */
			/****************/
			if ( d != 0 ) {
				/*  123456789 123456789 123456789 123456789 1234 */
				/* 001  [92/05/04 16:00]  NAA02244      オープン */
				if ( isSearchId( CPDS + 23 ) == YES ) {
					/* 一致したので CATLOG.TMP に書き出す */
					checkSaveSayData( COLLECT_ID );
				};
			};
		};
		checkSkipUselessLine();
	};
}

static	void	checkHpMain()
{
	char	id_name[ 12 ] , *p;

	/* HP 設定者の ID 番号の入力を促す行？ */
	GET_LINE;
	checkSetLibNumber();
	if ( PSL != 10 )											return;
	if ( matchstr( PSP, "：") == NO )							return;

	/* ID名であるかチェック */
	p = skip_space( PSP + 2 );
	CopyAlnum8( id_name, p );	touppers( id_name );
	if ( isIDname( id_name ) != YES )							return;

	GET_LINE2	return;						/* パスワードの入力を促す行？ */
	IfMatchStrYes("パスワード") {
		GET_LINE2	return;					/* パスワードの行 */
		GET_LINE2	return;					/* ＨＰのタイトルの行 */
	};
	/* 1994.2.13 追加 */
	IfMatchStrYes( "HP>" ) {	*ForumNameLineSub = '\0';
	} else {
		present_str_copy( ForumNameLineSub );
		sprintf( ForumNameLine , "HP:%s【%s】",id_name,ForumNameLineSub);
	};

	do {
		GET_LINE;		checkSetLibNumber();
		if ( checkCheckEnd() == YES )	break;
	} while ( isHpHyoudaiLine(PSP) == NO );
	checkHpLoop( id_name );
}

/**********************************************************************
>          1         2         3         4  
> 123456789 123456789 123456789 123456789 12
> 1  山本　年秀　　　  NAA02244  05/05 13:12
>    題名：まだちょっとおかしい...
***********************************************************************/
static	void	checkSaveStartMail( int mesNum )
{
	SayNum = atoi( CPDS );					/* 発言番号 */
	checkSetSayDate( MAIL, CPDS );			/* 日付 */
	ComNum = 0;								/* コメント元番号 */
	sprintf( ForumNameLine , "- MAIL:%sからのメールです。", ForumName );
	*ForumNameLineSub = '\0';
	if ( WithoutMAILSaySw == YES )			return;
	strncpy( Handle, CPDS + 4 , 16 );
	Handle[ 16 ]= '\0';
	strcpy( SayId, ForumName );
	checkSaveSayData( mesNum );
}

static	void	checkMail()
{
	FILE	*fpo;
	char	fileName[ 128 ];

	while (	isMailFirstLine(PSP,NSP) == YES ) {
		CPDS = PSP;
		BStart				= pool_seek_ichi;
		saveSayData.GStart	= PoolGyou;

		if (	WithoutMAILSaySw == YES
		||		check_SearchSayDate( PSP+32 , YES ) == NO
		) {
			GET_LINE2	break;
			checkSetLibNumber();
			checkSkipUselessLine();
			continue;
		};

		/* 発信者のＩＤ ＝ フォーラム名 */
		/*
		0         1         2         3         4  
		 123456789 123456789 123456789 123456789 12
		 1  山本　年秀　　　  NAA02244  05/05 13:12
		*/
		CopyAlnum8( ForumName , PSP + 22 );

		next_str_copy( HyoudaiLine );
		Hyoudai = HyoudaiLine + 10;			// NAA02244

		/* 1994.2.2 追加  ID_HANDLE_FILE_NAME  を作る為に */
		/* ＩＤ.TMP に ID と ハンドルを書き出す */
		strncpy( str, PSP + 3 , 17 );
		str[ 17 ] = '\0';
		SetTmpDirFile( fileName, ID_TMP_FILE_NAME );
		if ( ( fpo = fopen( fileName, "a" ) ) == NULL ) {
			strcpy( FileName, fileName );
			error_open_file( "ＩＤ.TMPを書き出す" );
			CATLOG_exit( 1 );
		};
			fprintf( fpo, "%-8s %-17s\n", ForumName, str );
		fclose( fpo );

		/******************************************/
		/* 先ず、この発言を CATLOG.TMP に書き出す */
		/******************************************/
		*SayId = '\0';		/* 1992.9.9 これがなかったために……… */
		MesNum = MAIL;				/* 会議室番号 */
		GET_LINE;
		checkSetLibNumber();
		while ( isMailFirstLine(PSP,NSP) != YES ) {
			GET_LINE2 break;	checkSetLibNumber();
			if ( checkCheckEnd() == YES ) break;
		};
		BEnd= pool_seek_ichi;
		checkSaveStartMail( MAIL );

		/* mail の本文を書き出す */
		if ( WithoutMAILSaySw == NO ) {
			/****************/
			/* ＩＤで収集？ */
			/****************/
			if ( isSearchId( ForumName ) == YES ) {		/* sub.c */
				/* 一致したので CATLOG.TMP に書き出す */
				checkSaveStartMail( COLLECT_ID );
			};
		};
		checkSkipUselessLine();
	};
}

/****************************************************************/
/*****************************************************************
>ID (改行のみ：自分のパティオ)
>：NAA02244
>パスワード
>：
>番号　発言 (未読) 　最新　　会議室名
> 1      60 (  60)   12/18   ＣＡＴＬＯＧの部屋だよ
  123456789 123456789 123456789 123456789 123456789 123456789
>00001/00060 NAA02244  飛雪　　　       ご利用に際しての注意
>( 1)   92/12/14 00:06
>PATIO(R)>
>PATIO(N)>
>PATIO(C)>
>読む (1:表示　改行のみ：次タイトル)
>＞
*****************************************************************/
/****************************************************************/
static	void	check_patio_loop( const char *id_name )
{
	int		i , mode;
	char	now[ 8 ] , *p1;

	/* フォーラム名 */
	strcpy( ForumName , id_name );
	mode = FORUM_IN_MODE;
	initial_kaigishitsu_name();

	MesNum = PATIO;
	checkSkipUselessLine();	/* 必要のない行を読み飛ばす */

	/* now の設定 */
	get_mes_now_number( PSP , now );	/* sub.c */

	sprintf( ForumNameLine, "PATIO:%s です。" , id_name );
	*ForumNameLineSub = '\0';

	while ( isPATIOFirstLine() == YES ) {
		CPDS = PSP;
		BStart				= pool_seek_ichi;
		saveSayData.GStart	= PoolGyou;
		present_str_copy( HyoudaiLine );
		GET_LINE2	 break;	/* 先読み */
		present_str_copy( MesNumberLine );
		GET_LINE2	 break;	/* 先読み */
		checkSetLibNumber();

		if (	WithoutPATIOSaySw == YES
		||		check_SearchSayDate( MesNumberLine + 7 , NO ) == NO
		) {
			skip_1_say( now , mode );
			continue;
		};
		/****************************/
		/* 削除した発言は登録しない */
		/****************************/
		if ( DeleteDeletedSaySw == YES ) {
			if (	*( HyoudaiLine + 12 ) == '*'
			||		strncmp( HyoudaiLine + 39 , "発言者削除" , 10 ) == 0
			) {
				skip_1_say( now , mode );	continue;
			};
		};
		/* 会議室を表す行をセット */
		i = atoi( MesNumberLine + 1 );	/* 会議室番号 */
		if ( 0<i && i<21 ) {
			if ( *KNL[ i ] != '\0' ) {
				strcpy(	ForumNameLineSub , KNL[ i ] );
			};
		} else {
				*ForumNameLineSub = '\0';
		};
		*SayId = '\0';
		/* 会議室番号 */
		MesNum = PATIO;
		forever {
			if (	checkCheckEnd() == YES
			&&		is_1_say_end( now , mode ) == YES
			) {
					break;
			};
					/* 123456789 123456789 123456789 */
			IfMatchStrYes("続き（改行で表示　S:次の発言）") {
				if (	NSL == 2
				&&	strncmp( NSP , "＞" , 2 ) == 0
				) {
					/* 2行 読み飛ばす */
					GET_LINE2 break;	/* 先読み */
					GET_LINE2 break;	/* 先読み */
					continue;
				};
			};
			GET_LINE2 break;	/* 先読み */
			checkSetLibNumber();
		};
		BEnd= pool_seek_ichi;
		strcpy( ForumName , id_name );						// フォーラム名
		MesNum = PATIO;
		if ( WithoutPATIOSaySw == NO ) {
			checkSaveStartMes( PATIO );
			/****************/
			/* ＩＤで収集？ */
			/****************/
			p1 = HyoudaiLine + 12;
			if ( isSearchId( p1 ) == YES )	checkSaveStartMes( COLLECT_ID );
		};
		if ( isPATIOFirstLine() == NO )	checkSkipUselessLine();
	};
}

static	void	checkPatioMain()
{
	char	id_name[ 12 ] , *p;

	/* PATIO 設定者の ID 番号の入力を促す行？ */
	GET_LINE;
	checkSetLibNumber();
	if ( PSL != 10 )								return;
	if ( matchstr( PSP, "：") != YES )				return;

	p= skip_space( PSP + 2 );

	strncpy( id_name , p , 8 );	/* copy ID */
	id_name[ 8 ] = '\0';
	touppers( id_name );							/* 大文字にする */
	/* ID名であるかチェック */
	if ( isIDname( id_name ) != YES )				return;

	check_patio_loop( id_name );
}

static	void	check_clip_skip()
{
	forever {
		IfMatchStrYes("＞")					break;
		GET_LINE;
	};
	GET_LINE;	/* 先読み */
}

static	void	checkClipMain()
{
	GET_LINE;
	check_clip_skip();
	check_clip_skip();
	checkSkipUselessLine();
	while (	isCLIPLine( PSP ) == YES ) {
		CPDS = PSP;
		BStart				= pool_seek_ichi;
		saveSayData.GStart	= PoolGyou;
		/* フォーラム名 */
		strcpy( ForumName , "CLIP" );					/* フォーラム名 */
		MesNum = CLIP;									/* 会議室番号 */
		SayNum = atoi( PSP );							/* 発言番号 */
		checkSetSayDate( CLIP, PSP );					/* 日付 sub.c */
		ComNum = 0;										/* コメント元番号 */
		*SayId = '\0';									/* 発言の収集 */
		present_str_copy( ForumNameLine );
		*ForumNameLineSub = '\0';
		GET_LINE;	checkSetLibNumber();
		while ( isCLIPLine( PSP ) != YES ) {
			GET_LINE2 break;	checkSetLibNumber();
			if ( checkCheckEnd() == YES ) break;
		};
		BEnd= pool_seek_ichi;
		*Handle = *SayId = '\0';
		Hyoudai = NULL;
		checkSaveSayData( CLIP );
		checkSkipUselessLine();
	};
}

//	###########################################################################
//	##### Check1File ##########################################################
//	###########################################################################
static	char	*RenameAttrStr = "_-~#$%&()@{}!｢｣[]ｱｲｳｴｵｶｷｸｹｺｻｼｽｾｿﾀﾁﾂﾃﾄﾅﾆﾇﾈﾉﾊﾋﾌﾍﾎﾏﾐﾑﾒﾓﾔﾕﾖﾗﾘﾙﾚﾛﾜﾝ";
void	Check1File( const char *file, const char *name )
{
			int		d;
			int		isCatlogFileSw ;
	const	char	*cp;
			char	inDirSub[ MAX_FILENAME_LEN ];
	char	fileName[ MAX_FILENAME_LEN ], attrib[ 20 ];
			char	forumName[ 20 ], *p1, *p2;
			long	fsize;

	CheckAbort();
	if ( CheckAbortSw == YES )							return;


#ifdef	TMENU
#ifndef	CATLOG_EXG		// EXP 版の場合
	// LZH ファイルの場合
	cp = last_comma( name );
	if (	ReStoreLZHSw == YES
	&&		strcmp( cp, ".LZH" ) == 0
	) {
		char	*p3;
		int		deleteOldFileSw, storeLZHSw ;

		// 残りディスク容量のチェックを行う
			fsize= GetFileSize( name ) * 3 ;	// 圧縮率 33 ％として計算
			if ( FM_GetDiskFreeSize( *TmpDir ) < fsize ) {
				PrintMessage(
"\nＴＭＰディレクトリの残り容量が少ないのでこれまで見つけた発言を整理します。"
				);
				// 第３段階の実行
				CheckMainCatlogMain();
				AllHatsugenSu = 0;
				CollectFileSize = 0L;
				if ( CheckAbortSw == YES )							return;
			};

		// Lzh ファイルを解凍する
		// lha -x <file> <inDirSub>\ 
			SpawnTree( "LHA.EXE" );
			SpawnTree( "x" );
			SpawnTree( file );
		// 解凍先の指定
			strcpy( str, file );
			p1= str;	if ( *(p1+1) == ':' )	p1 += 2;
			if ( *p1 == '\\' )	p1++;
			p2= last_yen( p1 );
			p3= last_comma( p2 );
			if ( p2 != p3 )		*p3= '\0';		// 拡張子を削除
			SetTmpDirFile( inDirSub, p1 );
			append_yen( inDirSub );
			SpawnTree( inDirSub );

		// spawn
		collect_system( "LHA.EXE" );

		deleteOldFileSw=		DeleteOldFileSw ;
			DeleteOldFileSw= YES;					// YES  : 削除する
		storeLZHSw=				StoreLZHSw ;
			StoreLZHSw = NO;						// Lzh 圧縮を OFF に
			ForceDeleteOldFileSw= YES;
				CheckMainLoop( inDirSub );
			ForceDeleteOldFileSw= NO;
		StoreLZHSw=				storeLZHSw ;			// 元に戻す
		DeleteOldFileSw=		deleteOldFileSw ;		// 元に戻す
		isCatlogFileSw = 0;
		goto Check1FileJump;
	};

#endif	// ! CATLOG_EXG
#endif	// TMENU

	/**********/
	/* 初期化 */
	/**********/
#ifdef		DO_ON_MEMORY					// メモリ上で処理を行う
	// SayData の値の初期化
	IdxP = 0;
#endif

	// ファイル検索条件に合う？
	if ( isSearchFile( file, name ) == NO )						return;

	if ( isWithoutSearchFile( file, name ) == YES ) {
		if ( ForceDeleteOldFileSw == YES ) {
			// ファイルを削除する
			remove( file );
		};
		return;
	};

	/* CATLOGで整理したファイル？ */
	MesNum= HatsugenSu= 0;
	isCatlogFileSw = isCATLOGFile( file );

	if ( isCatlogFileSw == COLLECT_ID )				return;		// 単に無視する

	strcpy( fileName, file );	strcpy( attrib, name );

	if (	isCatlogFileSw != 0
	&&		CheckAndMakeCatlog2IndexSw == NO
	&&		SearchIdSayMainSw == NO
	) {
		// CATLOG ファイルの拡張子を ._?? に変更する
		p1= last_comma( fileName );
		if ( p1 == fileName ) {				// 拡張子が無い
			strcat( fileName, ".BAK" );
			strcat( attrib  , ".BAK" );
		};
		p1= last_comma( fileName ) + 1;
		p2= last_comma( attrib )   + 1;
		// ファイル名を変更する				// file → fileName
		for ( cp= RenameAttrStr; *cp != '\0' ; cp++ ) {
			*p1 = *cp;
			*p2 = *cp;
			// rename( old, New );
			if ( rename( file, fileName ) == 0 )	break;
		};
		if ( *cp == '\0' ) {
#ifdef	TMENU
			sprintf( YesNoMes,
"\n"
"rename <%s>→<%s> が出来ませんのでこのファイルは無視します"
				,file, fileName
			);
			PrintMessage( YesNoMes );
#endif
			goto Check1FileJump;
		};
	};

/*
 1     1 9303111234 FFMHOB        171     0
*/
	// 残りディスク容量のチェックを行う
	fsize= GetFileSize( fileName );
	if (
#ifdef	TMENU
			FM_GetDiskFreeSize( *OutDir )
#else
			1024L * 1024L
#endif
	< 
			CollectFileSize * 3 / 2 + fsize + ( 46 * 3 / 2 ) * AllHatsugenSu
	) {
#ifdef	TMENU
		PrintMessage(
"\n出力ディレクトリの残り容量が少ないのでこれまで見つけた発言を整理します。"
		);
#endif
		// 第３段階の実行
		CheckMainCatlogMain();
		AllHatsugenSu = 0;
		CollectFileSize = 0L;
		if ( CheckAbortSw == YES )								return;
		isCatlogFileSw = isCATLOGFile( fileName );
	};

	/******************/
	/* 発言の探索開始 */
	/******************/
	mess_check	disp_start_check_file( file, fsize );

	strcpy( SaveSayDataFileName, fileName );
	strcpy( FileName, fileName );
	if ( initial_check_pool( fileName ) == YES ) {
		// ファイルにデータを書き出す
		if ( isCatlogFileSw != 0 ) {
			Check1FileCatlog();
		} else if ( CheckRtBbsLogSw == YES ) {
			Check1FileRtBbs( YES );
		} else {
			// 最後のフォーラム名らしきものを forumName に入れる
			*forumName= '\0';
			cp= file;
			if ( *(cp+1) == ':' )	cp += 2;
			if ( *cp == '\\' )		cp++;
			while( *cp ) {
				if (	matchstr( cp, "$$$%%%%%" ) == YES
				||		matchstr( cp, "F$" ) == YES
				) {
					cp= (const char *)CopyAlnum8( forumName, cp );
				};
				while( *cp ) {
					if ( *cp == '\\' ) {	cp++;		break;	};
					cp++;
				};
			};
			forever {
				CPDS = PSP;
				if ( check_start_line() != 0 ) {
					MesNum = 0;
					while ( ( d = check_start_line() ) != 0 ) {
						switch ( d ) {
							case 1:	// ﾌｫｰﾗﾑの入口
								checkForumMode();						break;
							case 2:	// ﾌｫｰﾗﾑ名がある場合  - Fxxxxの場合
								checkForumNameMode();				break;
							case 3:	// ﾌｫｰﾗﾑ名がない場合  xxx/xxxからの場合
								checkHyoudaiLineMode( forumName );	break;
							case 4:	// Home Party の入口
								checkHpMain();							break;
							case 5:	// Mail の入口
								checkMail();							break;
							case 6:	// Bill の入口
								checkBill();							break;
							case 7:	// HP の発言
								sprintf( ForumNameLine,
									"- HP:%sのHome Partyです。",forumName);
								checkHpLoop( forumName );				break;
							case 8: // LIB の入口
								checkLibMain( forumName );				break;
							case 9: // PATIO の入口
								checkPatioMain();						break;
							case 10:	// クリッピングサービスの入口
								checkClipMain();						break;
							default:									break;
						};
					};
				} else {
					GET_LINE2 break;		checkSetLibNumber();
				};
			};
		};
		end_check_pool( );
		AllHatsugenSu  += HatsugenSu;
#ifdef	TMENU
		mess_check
		{
			if ( HatsugenSu == 0 ) {
				PrintMessage( "発言なし" );
			} else {
				sprintf(YesNoMes,"%4d 個 合計%5d 個",HatsugenSu,AllHatsugenSu);
				PrintMessage( YesNoMes );
			};
		};
#endif
	};

Check1FileJump:

	if ( isCatlogFileSw != 0 ) {
		// 整理済ファイルの場合
		// インデックスの作り直しの場合、元ファイルは削除しない
		if ( CheckAndMakeCatlog2IndexSw == YES )			return;
		// ＩＤでの発言検索の場合、元ファイルは削除しない
		if ( SearchIdSayMainSw == YES )						return;
		if ( HatsugenSu != 0 ) {
			// 強制的に削除するファイルに追加しておく
			// 強制的に↓
			// 「削除するファイル」の一覧ファイルにファイル名を追加する
			{
				FILE	*fpo;
			
				SetTmpDirFile( inDirSub, FORCE_DEL_FILE_TABLE_FILE_NAME );
				if ( ( fpo= fopen( inDirSub, "a" ) ) == NULL ) {
					er_open(inDirSub,1,"強制的に削除するファイル名のオープン");
				};
				fprintf( fpo, "%s\n", fileName );
				fclose( fpo );
			};
			if ( matchstr2( file, OutDir ) == YES ) {
				// インデックスから fileNum のデータを削除する
				// 1995.6.18 追加
				DeleteIndexData( ForumName, MesNum, GetCatlogFileNum( file ) );
			};
		} else {
			// ファイル名を元に戻しておく → 削除されない
			// CATLOG ファイルの拡張子を ._?? に変更する
			// rename( old, New );
			if ( rename( fileName, file ) != 0 ) {
				sprintf( YesNoMes,
					"\n" "rename <%s>→<%s> が出来ません",
					 file, fileName
				);
				showKakunin( YesNoMes );
			};
		};
		return;
	};

	if ( ForceDeleteOldFileSw == YES ) {
		if ( HatsugenSu == 0 ) {
			// このファイルを削除する
#ifdef	TMENU
			mess_check	PrintMessage( " ← 強制削除" );
#endif
			remove( file );
		};
		return;
	};

	// インデックスの作り直しの場合、元ファイルは削除しない
	if ( CheckAndMakeCatlog2IndexSw == YES )					return;
	// ＩＤでの発言検索の場合、元ファイルは削除しない
	if ( SearchIdSayMainSw == YES )								return;

	// このファイルを削除する？
	if (	DeleteOldFileSw == NO
	||		isDeleteOldFile( attrib ) == NO
	)															return;

#ifdef	TMENU
	mess_check	PrintMessage( " ← 削除対象" );
#endif

	// 「削除するファイル」の一覧ファイルにファイル名を追加する
//	if ( HatsugenSu != 0 ) {
		{
			FILE	*fpo;

			SetTmpDirFile( inDirSub, DEL_FILE_TABLE_FILE_NAME );
			if ( ( fpo= fopen( inDirSub, "a" ) ) == NULL ) {
				er_open( inDirSub, 1, "Check1File" );
			};
			fprintf( fpo, "%s\n", fileName );
			fclose( fpo );
		};
//	};
}

/* DIVIDE_END */

/* DIVIDE_START=..\common_r.c */
// このファイルはRT-BBS関連の共通処理を行う部分である
/*
	AccessRtBbs
		AccessRtBbsBufPtr
		AccessRtBbsAutoMode
			FORUMup		発言をアップする
				CHKcom1
		isEscChar
	cputs consol/consol.c で定義
	RtBbsWithOutQuit
		RtBbsExMoreSw
		RtBbsApply			サインアップ
*/

#ifdef		TMENU	
#include	"common.h"

#ifndef		CATLOG_EXG
#include	"consol.h"
//	#include <conio.h>
#endif	// ! CATLOG_EXG

#include	<mos.h>
#include	<fmcfrb.h>
#include	<string.h>

#ifndef		CATLOG_EXG
#include	<rs.h>
#endif	// ! CATLOG_EXG

#include	<time.h>

#define		COMMON_R	1
#include	"common_r.h"

int		DownRtBbsBoadSw = YES;

void	CheckAndSetTidyRtBbsName( char *forumName );

void	SetRtBbsListMenuSub( )
{
	struct	RtBbsData	*bbs;

	for ( bbs= pRtBbsData; bbs != NULL ; bbs=bbs->next ) {
		if ( strcmp( bbs->Name, rtBbsTmp.Name ) == 0 ) {
			rtBbsTmp.next = bbs->next;
			*bbs = rtBbsTmp;
			return;
		};
	};
	if ( pRtBbsData == NULL ) {
		pRtBbsData= bbs= TL_calloc( 1, sizeof( struct RtBbsData ) );
	} else {
		for ( bbs= pRtBbsData; bbs->next != NULL ; bbs=bbs->next ) ;
		// 構造体用のメモリーを確保する
		bbs->next= TL_calloc( 1, sizeof( struct RtBbsData ) );
		if ( bbs->next == NULL ) {
			PrintMessage( "\nメモリーが足りません" );
			return;
		};
		bbs= bbs->next;
	};
	*bbs = rtBbsTmp;
	bbs->next= NULL;
	CheckAndSetTidyRtBbsName( bbs->DirName );
}

/*
int		SetRtBbsInsideData( const char *name )
{
	struct	RtBbsData	*bbs;

	for ( bbs=pRtBbsData; bbs != NULL ; bbs= bbs->next ) {
		if ( strcmp( bbs->Name, name ) == 0 )		break;
	};
	if ( bbs->Name == NULL )						return( NO );
	rtBbsTmp = *bbs;
	return( YES );
}
*/
char	*getRtBbsDirName( const char *name )
{
	struct	RtBbsData	*bbs;

	for ( bbs=pRtBbsData; bbs != NULL ; bbs= bbs->next ) {
		if ( name == NULL )								break;
		if ( strcmp( bbs->DirName, name ) == 0 ) {
			bbs = bbs->next;
			break;
		};
	};
	if (	*bbs->Name == '\0'
	||		bbs->Name == NULL
	||		bbs == NULL
	)														return( NULL );
	rtBbsTmp = *bbs;
	return( rtBbsTmp.DirName );
}

void	SaveRtBbsName( FILE *fpo )
{
	struct	RtBbsData	*bbs;

	for ( bbs= pRtBbsData; bbs != NULL ; bbs=bbs->next ) {
		fprintf( fpo,	"RT-BBS:%s,%s,%s,%s,%s,%s,"
						"%s,%d,"		// tel1
						"%s,%d,"		// tel2
						"%s,%d,"		// tel3
						"%s,%d"			// tel4
						"\n"
				, bbs->Name
				, bbs->DirName
				, bbs->path
				, bbs->id
				, bbs->passWord
				, bbs->Handle
				
				, bbs->tel1
				, bbs->speed1
				, bbs->tel2
				, bbs->speed2
				, bbs->tel3
				, bbs->speed3
				, bbs->tel4
				, bbs->speed4
		);
	};
}

void	SetRtBbsListMenu( char *option )
{
	char	*p;
	char	speed[ 20 ];

	// ＲＴ−ＢＢＳ名
	p = CopyWord( rtBbsTmp.Name, option, 40-1 );
	// ディレクトリ名
	p = CopyWord( rtBbsTmp.DirName, p, 12-1 );
	// ログ・ディレクトリ
	p = CopyWord( rtBbsTmp.path, p, MAX_FILENAME_LEN -1 );
	// ＩＤ
	p = CopyWord( rtBbsTmp.id,   p, 10-1 );
	// パスワード
	p = CopyWord( rtBbsTmp.passWord, p, 10-1 );
	// ハンドル
	p = CopyWord( rtBbsTmp.Handle, p, 20-1 );
	// 電話番号
	p = CopyWord( rtBbsTmp.tel1, p, 40-1 );
	p = CopyWord( speed, p, 20-1 );	rtBbsTmp.speed1 = atoi( speed );
	p = CopyWord( rtBbsTmp.tel2, p, 40-1 );
	p = CopyWord( speed, p, 20-1 );	rtBbsTmp.speed2 = atoi( speed );
	p = CopyWord( rtBbsTmp.tel3, p, 40-1 );
	p = CopyWord( speed, p, 20-1 );	rtBbsTmp.speed3 = atoi( speed );
	p = CopyWord( rtBbsTmp.tel4, p, 40-1 );
	p = CopyWord( speed, p, 20-1 );	rtBbsTmp.speed4 = atoi( speed );
	SetRtBbsListMenuSub( );
}

void	SaveRtBbsName2( )
{
	struct	RtBbsData	*bbs;
			FILE		*fp;
			char		fileName[ MAX_FILENAME_LEN ];
			char		form[ 40 ];
			int			max;

	max= 0;
	for ( bbs= pRtBbsData; bbs != NULL ; bbs=bbs->next ) {
		if ( max < strlen( bbs->Name ) )	max= strlen( bbs->Name );
	};
	max += 2;
	sprintf( form, "%%%ds %%s\n", -max );

	// CheckRtBbsFile YamaBbsFunc
	SetTmpDirFile( fileName, TMP_FILE_NAME );
	if ( ( fp= fopen( fileName, "w" ) ) == NULL ) {
		er_open( fileName, 1, "RT-BBS局名の書き出し" );
	};
	for ( bbs= pRtBbsData; bbs != NULL ; bbs=bbs->next ) {
		fprintf( fp, "%s\n", bbs->Name );					// 書き出す文字列
//		fprintf( fp, "%-40s %s\n", bbs->Name, bbs->path );	// 表示する文字列
		fprintf( fp, form,         bbs->Name, bbs->path );	// 表示する文字列
	};
	fprintf( fp, "新規登録\n" );
	fprintf( fp, "新規登録\n" );
	fclose( fp );
}

int		isRtBbsName( char *name )
{
	struct	RtBbsData	*bbs;

	for ( bbs= pRtBbsData; bbs != NULL ; bbs=bbs->next ) {
		if ( matchstr2( name, bbs->DirName ) == YES ) {
			rtBbsTmp = *bbs ;
			return( YES );
		};
	};
	return( NO );
}

int		isRtBbsName2( char *name )
{
	struct	RtBbsData	*bbs;

	for ( bbs= pRtBbsData; bbs != NULL ; bbs=bbs->next ) {
		if ( strcmp( bbs->Name, name ) == 0 ) {
			rtBbsTmp = *bbs ;
			return( YES );
		};
	};
	return( NO );
}

//	###########################################################################
//	##### 通信処理 ############################################################
//	###########################################################################
static	struct	NetName	{
			char	name1[ 40 ];			// 標題として使う
			char	tel1[ 40 ];		int		speed1;
			char	tel2[ 40 ];		int		speed2;
			char	tel3[ 40 ];		int		speed3;
			char	tel4[ 40 ];		int		speed4;
			char	name2[ 40 ];			// 変更不可：CATLOG2.DEFに書き出す
			char	name3[ 12 ];			// ８バイトまで
} NetName[] = {
{	"いわき THE BEAT-NET",
	"0246-27-8368",9600,				"",0,
	"",0,								"",0,
	"THE BEAT-NET",						"TBN"
},
{	"八王子 ミンキームーン　ネットワーク",
	"0426-48-3881",38400,				"0426-43-3292",19200,
	"", 0,								"", 0,
	"ミンキームーン　ネットワーク",		"MMN"
},
/*
{	"川　崎 きまぐれ☆ＮＥＴ",
	"044-798-3665",14400,				"044-798-1748",14400,
	"",0,									"",0,
	"きまぐれ☆ＮＥＴ",					"MDN"
},
*/
{	"松　戸 KT-Network",
	"0473-44-5862",14400,				"",0,
	"",0,								"",0,
	"KT-Network",						"KTN"
},
{	"諏　訪 信州サミットネット",
	"0266-79-6364",2400,				"0266-79-5926",9600,
	"0266-79-4914",14000,				"",0,
	"サミットネット",					"SUM"
},
{	"名古屋 ＪＭＪ−ＮＥＴ",
	"052-483-0636",9600,				"",0,
	"",0,								"",0,
	"ＪＭＪ−ＮＥＴ",					"JMJ"
},
/*
{	"名古屋 ＭＩＮＡ−ＮＥＴ",
	"052-972-6430",14400,				"",0,
	"",0,								"",0,
	"ＭＩＮＡ−ＮＥＴ",					"MIN"
},
*/
{	"岡　崎 ＴＧＫ−ＮＥＴ",
	"0564-24-5531",14400,				"",0,
	"",0,								"",0,
	"ＴＧＫ−ＮＥＴ",					"TGK"
},
{	"安　城 オレンジ　ネット",
	"0566-22-5089",14400,				"",0,
	"",0,								"",0,
	"オレンジ”ネット",					"OTT"
},
{	"安　城 ＭＮＫ’ｓ　ＢＢＳ",
	"0566-98-1639",9600,				"0566-98-6946",9600,
	"0566-98-9374",2400,				"",0,
	"ＭＮＫ’ｓ　ＢＢＳ",				"MNK"
},
{	"碧　南 ＪＣ−ＮＥＴ",
	"0566-42-1838",14400,				"",0,
	"",0,								"",0,
	"ＪＣ−ＮＥＴ",						"JCN"
},
{	"豊　川 ＩＴＹ−Ｎｅｔ",
	"05338-2-2622",14400,				"",0,
	"",0,								"",0,
	"ＩＴＹ−Ｎｅｔ",					"ITY"
},
{	"春日井 ＫＭＦ−Ｎｅｔ",
	"0568-83-4416",14400,				"0568-83-4859",14400,
	"",0,								"",0,
	"ＫＭＦ−Ｎｅｔ",					"KMF"
},
{	"大　阪 アリス　ネット",
	"06-882-0685",9600,					"06-882-0172",9600,
	"06-882-0690",9600,					"06-882-1733",9600,
	"大　阪 アリス　ネット",			"ALS"
},
{	"枚　方 Ｙａｍａ−ＢＢＳ",
	"0720-50-9412",9600,				"",0,
	"",0,								"",0,
	"Ｙａｍａ−ＢＢＳ",					"Yama-BBS"
},
{	"寝屋川 ＤＩＧＩＴＡＬ−ＢＢＳ",
	"0720-39-4459",144000,				"0720-39-4460",144000,
	"0720-39-4461",144000,				"0720-39-4462",144000,
	"ＤＩＧＩＴＡＬ−ＢＢＳ",			"DIG"
},
{	"姫　路 ＭＯＳ−ＮＥＴ",
	"0792-45-9410",9600,				"",0,
	"",0,								"",0,
	"ＭＯＳ−ＮＥＴ",					"MOS"
},
{	"宮　崎 オビ−ネット[社会人のみ対象]",
	"0987-25-2599",14400,				"",0,
	"",0,								"",0,
	"オビ−ネット",						"OBI"
},
{	"那　覇 サラダハウス−ＢＢＳ",
	"0988-57-5791",14400,				"",0,
	"",0,								"",0,
	"サラダハウス−ＢＢＳ",				"SAR"
},
{	"",	"",0,	"",0,	"",0,	"",0,	"",	""
}
};

void	OutDoraData( const char *tmp )
{
			FILE		*fp;
			char		fileName[ MAX_FILENAME_LEN ];
	struct	NetName		*netName;

	SetTmpDirFile( fileName, tmp );
	if ( ( fp= fopen( fileName, "w" ) ) == NULL ) {
		er_open( fileName, 1, "Tmp へのＲＴ−ＢＢＳ名の書き出し" );
	};
	for ( netName=NetName; *netName->name1 ; netName++ ) {
		fprintf( fp, "%s\n",    netName->name1 );		// 書き出す文字列
		fprintf( fp, "%-40s %s\n", netName->name1, netName->tel1 );
														// 表示する文字列
	};
	fprintf( fp, "新規登録\n" );
	fprintf( fp, "新規登録\n" );
	fclose( fp );
}

void	OutDoraData2( const char *tmp )
{
			FILE		*fp;
			char		fileName[ MAX_FILENAME_LEN ];
	struct	NetName		*netName;

	SetTmpDirFile( fileName, tmp );
	if ( ( fp= fopen( fileName, "w" ) ) == NULL ) {
		er_open( fileName, 1, "Tmp へのＲＴ−ＢＢＳ名の書き出し" );
	};
	for ( netName=NetName; *netName->name1 ; netName++ ) {
		fprintf( fp, "%s\n",    netName->name1 );		// 書き出す文字列
		fprintf( fp, "%-36s %s\n", netName->name1, netName->tel1 );
														// 表示する文字列
	};
	fclose( fp );
}

int		SetRtBbsDoraData( const char *name )
{
	struct	NetName		*netName;

	for ( netName=NetName; *netName->name1 ; netName++ ) {
		if ( strcmp( netName->name1, name ) == 0 )		break;
	};
	if ( *netName->name1 == '\0' )						return( NO );
	strcpy( rtBbsTmp.Name, netName->name2 );
	strcpy( rtBbsTmp.DirName, netName->name3 );
	strcpy( rtBbsTmp.path, RtBbsRootDir );	append_yen( rtBbsTmp.path );
	strcat( rtBbsTmp.path, netName->name3 );
	*rtBbsTmp.id = *rtBbsTmp.passWord = '\0';
	strcpy( rtBbsTmp.Handle, MyHandle );
	strcpy( rtBbsTmp.tel1, netName->tel1 );
	strcpy( rtBbsTmp.tel2, netName->tel2 );
	strcpy( rtBbsTmp.tel3, netName->tel3 );
	strcpy( rtBbsTmp.tel4, netName->tel4 );
	rtBbsTmp.speed1 = netName->speed1;
	rtBbsTmp.speed2 = netName->speed2;
	rtBbsTmp.speed3 = netName->speed3;
	rtBbsTmp.speed4 = netName->speed4;
	return( YES );
}

struct	MODEM	{
		char	*mes1;
		char	*para1;
		char	*para2;
		char	*mes2;
};
struct	MODEM	FUJITSU[] = {
{	"富士通 内蔵1200",	"X3",	"",						"内蔵1200_1200n"	},
{	"富士通 内蔵2400",	"X3",	"\\N2\\V1\\Q3\\J0%C1",	"内蔵2400_9600m"	},
{	"富士通 PM1200F",	"X3",	"",						"PM1200F_1200n"		},
{	"富士通 PM2400F",	"X3",	"\\N2\\Q3\\J0%C1",		"PM2400F_9600m"		},
{	"富士通 PM2400FII",	"X3",	"\\N6\\Q3\\J0\\V2%C1",	"PM2400FII_9600m"	},
{	"富士通 OAMD-301",	"X3&D2","\\N2\\Q3\\J0\\V2",		"OAMD-301_9600m"	},
{	NULL,				NULL,	NULL,					NULL				}
};
struct	MODEM	AIWA[] = {
{	"AIWA PV-A1200",	"X3",	"",						"PV-A1200_1200n"	},
{	"AIWA PV-A2400",	"X3",	"",						"PV-A2400_2400n"	},
{	"AIWA PV-A2400MNP4","&D2",	"&M4\\Q1",				"PV-A2400MNP4_9600m"},
{	"AIWA PV-A24B5",	"X3&D2","\\N2\\Q3\\J0\\V2%C1",	"PV-A24B5_9600m"	},
{	"AIWA PV-A24MNP5",	"X3&D2","\\N2\\Q3\\J0",			"PV-A24MNP5_9600m"	},
{	"AIWA PV-A24V42",	"X3&D2","\\N2\\Q3\\J0",			"PV-A24V42_9600m"	},
{	"AIWA PV-A24V5",	"X3&D2","\\N2\\Q3\\J0\\V2%C1",	"PV-A24V5_9600m"	},
{	"AIWA PV-M24",		"X3&D2","\\N2\\Q3\\J0\\V2",		"PV-M24_9600m"		},
{	"AIWA PV-M24M5",	"X3&D2","\\N2\\Q3\\J0\\V2",		"PV-M24M5_9600m"	},
{	"AIWA PV-M24B5",	"X3&D2","\\N2\\Q3\\J0\\V2%C1",	"PV-M24B5_9600m"	},
{	"AIWA PV-A96V5",	"X3&D2","\\N2\\Q3\\J0\\V2%C1",	"PV-A96V5_19200m"	},
{	"AIWA PV-AF144V5",	"X4&D2","\\N2\\Q3\\J0\\V2%C1",	"PV-AF144V5_19200m"	},
{	NULL,				NULL,	NULL,					NULL				}
};
struct	MODEM	OMRON[] = {
{	"OMRON MD1200",		"X3",	"",						"MD1200_1200n"		},
{	"OMRON MD12FS",		"X3",	"",						"MD12FS_1200n"		},
{	"OMRON MD2400F",	"X3",	"\\N2\\V1\\Q2\\J0",		"MD2400F_2400m"		},
{	"OMRON MD24FB5V",	"X3",	"\\N2\\Q2\\J0\\V2%C1",	"MD24FB5V_9600m"	},
{	"OMRON MD24FP4",	"X3",	"\\N2\\Q2\\J0",			"MD24FP4_2400m"		},
{	"OMRON MD24FP4II",	"X3&P2","\\N2\\Q2\\J0",			"MD24FP4II_9600m"	},
{	"OMRON MD24FP5V",	"X3",	"\\N2\\Q2\\J0\\V2%C1",	"MD24FP5V_9600m"	},
{	"OMRON MD24FS4",	"X3",	"\\N2\\Q2\\J0",			"MD24FS4_2400m"		},
{	"OMRON MD24FS5",	"X3",	"\\N2\\Q2\\J0",			"MD24FS5_2400m"		},
{	"OMRON MD24FS7",	"X3",	"\\N2\\Q2\\J0",			"MD24FS7_2400m"		},
{	"OMRON MD246FL10V",	"X3",	"\\N2\\Q2%C1\\J0",		"MD24FL10V_9600m"	},
{	"OMRON MD24XL10V",	"X3",	"\\N2\\Q2%C1\\J0",		"MD24XL10V_9600m"	},
{	"OMRON MD24XT10V",	"X3",	"\\N2\\Q2%C1\\J0",		"MD24XT10V_9600m"	},
{	"OMRON MD96FB5V",	"X3",	"\\N2\\Q2%C1\\D0\\J0",	"MD96FB5V_19200m"	},
{	"OMRON MD96FL10V",	"X3",	"\\N2\\Q2%C1\\J0",		"MD96FL10V_19200m"	},
{	"OMRON MD96XL10V",	"X3",	"\\N2\\Q2%C1\\J0",		"MD96XL10V_19200m"	},
{	"OMRON MD96XT10V",	"X3",	"\\N2\\Q2%C1\\J0",		"MD96XT10V_19200m"	},
{	"OMRON MD144XT10V",	"X3",	"\\N2\\Q2%C1\\J0",		"MD144XT10V_19200m"	},
{	NULL,				NULL,	NULL,					NULL				}
};

struct	MODEM	EPSON[] = {
{	"EPSON SR-120S",	"X3",	"",						"SR-120S_1200n"		},
{	"EPSON SR-240AT",	"X3",	"",						"SR-240AT_2400n"	},
{	"EPSON SR-240V",	"X3\\V2","N1&K1%C1",			"SR-240V_9600m"		},
{	NULL,				NULL,	NULL,					NULL				}
};

struct	MODEM	NEC[] = {
{	"NEC COMSTAR 2424",	"X3",	"\\N2\\Q2",				"COMSTAR 2424_2400m"},
{	NULL,				NULL,	NULL,					NULL				}
};

struct	MODEM	SONY[] = {
{	"SONY IT-V1200",	"X3",	"",						"IT-V1200_1200n"	},
{	NULL,				NULL,	NULL,					NULL				}
};

struct	MODEM	MICROCORE[] = {
{	"MICROCORE MC24PA5","X3",	"\\N2\\Q2\\J0\\X1%C1",	"MC24PA5_9600m"		},
{	"MICROCORE MC14400FX","X3",	"\\N2\\Q2\\J0\\X1%C1",	"MC14400FX_19200m"	},
{	NULL,				NULL,	NULL,					NULL				}
};

struct	MODEM	PROSIDE[] = {
{	"PROSIDE PS-1414VQE","X3L1&D2","N1W1&K3&P3\\A3\\N2%C1","PS1414VQE_19200m"},
{	NULL,				NULL,	NULL,					NULL				}
};

struct	MODEM	NISSEI[] = {
{	"NISSEI FM9624",	"X3",	"\\N2\\Q3%C1",			"FM9624_9600m"		},
{	"NISSEI FM1414",	"X3",	"\\N2&K3%C3",			"FM1414_19200m"		},
{	NULL,				NULL,	NULL,					NULL				}
};

struct	MODEM	SUNTAC[] = {
{	"SUNTAC MS144AVF",	"X3",	"\\N2\\V2\\Q2\\J0\\X0%C1","MS144AVF_19200m"},
{	NULL,				NULL,	NULL,					NULL				}
};

struct	MODEM	DYNALINK[] = {
{	"DYNALINK 1414VE",
	"X3&D2",	"N1W1&K3&P2\\A3\\N2S95=46",			"DYNALINK1414VE_19200m"},
{	NULL,				NULL,	NULL,					NULL				}
};

struct	MODEM	BOCA[] = {
{	"BOCA RESEARCH M144JE","X3","&K3&P3\\J0\\A3\\N2",	"M144JE_19200m"		},
{	NULL,				NULL,	NULL,					NULL				}
};

struct	MODEM	PANASONIC[] = {
{	"PANASONIC TO-703B","X3&D2","\\N3\\Q3\\V2%C1",		"TO-703B_19200m"	},
{	NULL,				NULL,	NULL,					NULL				}
};


struct	ModemMaker	{
		char	*Maker;
		struct	MODEM	*Modem;
};
struct	ModemMaker	ModemMaker[] = {
	{	"ＦＵＪＩＴＳＵ",			FUJITSU		},
	{	"ＡＩＷＡ",					AIWA		},
	{	"ＯＭＲＯＮ",				OMRON		},
	{	"ＥＰＳＯＮ",				EPSON		},
	{	"ＮＥＣ",					NEC			},
	{	"ＳＯＮＹ",					SONY		},
	{	"マイクロコア",				MICROCORE	},
	{	"プロサイド",				PROSIDE		},
	{	"日成電機",					NISSEI		},
	{	"ＳＵＮＴＡＣ",				SUNTAC		},
	{	"ＤＹＮＡＬＩＮＫ",			DYNALINK	},
	{	"BOCA-RESEARCH",			BOCA		},
	{	"ＰＡＮＡＳＯＮＩＣ",		PANASONIC	},
	{	NULL,						NULL		},
};

// メモリー上のモデムのメーカー名をファイル<TMP_FILE_NAME>に書き出す
void	OutModemMaker()
{
			FILE		*fp;
			char		fileName[ MAX_FILENAME_LEN ];
	struct	ModemMaker	*maker;

	SetTmpDirFile( fileName, TMP_FILE_NAME );
	if ( ( fp= fopen( fileName, "w" ) ) == NULL ) {
		er_open( fileName, 1, "Tmp へのモデムのメーカー名の書き出し" );
	};
	for ( maker=ModemMaker; maker->Maker != NULL ; maker++ ) {
		fprintf( fp, "%s\n%s\n", maker->Maker, maker->Maker );
	};
	fclose( fp );
}

int		OutModemKisyu( const char *Maker )
{
			FILE		*fp;
			char		fileName[ MAX_FILENAME_LEN ];
			int			sw;
	struct	ModemMaker	*maker;
	struct	MODEM		*modem;

	for ( maker=ModemMaker; maker->Maker != NULL ; maker++ ) {
		if ( strcmp( maker->Maker, Maker ) == 0 )		break;
	};
	if ( maker->Maker == NULL )				return( NO );
	// モデムの種類を入力する
	// メモリー上のモデムの種類をファイル<TMP_FILE_NAME>に書き出す
	SetTmpDirFile( fileName, TMP_FILE_NAME );
	if ( ( fp= fopen( fileName, "w" ) ) == NULL ) {
		er_open( fileName, 1, "Tmp へのモデムの種類名の書き出し" );
	};
	sw = NO;
	for ( modem=maker->Modem; modem->mes1 != NULL ; modem++ ) {
		fprintf( fp, "%s\n%s\n", modem->mes1, modem->mes1 );
		sw= YES;
	};
	fclose( fp );
	return( sw );
}

void	getModemPara( char *trg, char *ModemKisyu )
{
	struct	ModemMaker	*maker;
	struct	MODEM		*modem;

	strcpy( trg, "AT" );
	for ( maker=ModemMaker; maker->Maker != NULL ; maker++ ) {
		// モデムの種類を入力する
		for ( modem=maker->Modem; modem->mes1 != NULL ; modem++ ) {
			if ( strcmp( ModemKisyu, modem->mes1 ) == 0 ) {
				sprintf( trg, "AT%s%s", modem->para1, modem->para2 );
				return;
			};
		};
	};
}

#ifndef	CATLOG_EXG

//	###########################################################################
//	##### 通信処理 ## 回線にアクセスする ######################################
//	###########################################################################
static	void	RtBbsWithOutQuit( char *fileName );
static	int		RtBbsExMoreSw = NO;
static	int		AccessRtBbsLogSw= YES;
static	char	*AccessRtBbsBuf;
static	char	*AccessRtBbsBufPtr;
static	char	*AccessRtBbsBufMax;
static	char	*AccessRtBbsChkBuf;
static	char	*AccessRtBbsChkBufPtr;
static	char	*AccessRtBbsChkBufMax;
static	int		EscOn= NO;

void	RSBraddr( )
{
	rcnt++;
}

static	void	OutLog( char *mes )
{
	while( *mes ) {
		if ( *mes == '\n' )		*AccessRtBbsBufPtr++ = CR;
		*AccessRtBbsBufPtr++ = *mes++;
	};
}

static	void	WriteLog( int XoffSw );

static	int		SendChar( char ch )
{
	unsigned	short	limit;		 /* 受信成功待ちループの最大値 */
				char	*mes;

	for ( limit=0; limit<0xffff; limit++ ) {
		if ( RSB_Send( RS232C_PORT, ch, &status ) == 0 )		return( YES );
	};
	WriteLog( NO );
	mes= "\n===> send error occured <===\n";
	cputs( mes );		OutLog( mes );
	return( NO );
}

static	int		SendStr( char *ptr )
{
	/* SEND ROUTINE */
	do {		RSB_Gettxlen(RS232C_PORT,&leng);
	} while( leng + strlen( ptr ) > RS_BUF_SIZE );

	for ( ; *ptr!='\0' ; ptr++ ) {
		if ( *ptr == '\n' ) {
			if ( SendChar( 0x0d ) != YES )			return( NO );
			if ( SendChar( 0x0a ) != YES )			return( NO );
		} else if ( SendChar( *ptr ) != YES )		return( NO );
	};
	return( YES );
}

// １行ずつファイルをアップする
static	void	SendFile( char *fileName )
{
	FILE	*fp;
	char	str[ LINE ];

	if ( ( fp = fopen( fileName, "r" ) ) == NULL )		return;
	while( fgets( str, LINE, fp ) != NULL ) {
		SendStr( str );
	};
	fclose( fp );
}

#define		XON		0x11
#define		XOFF	0x13

/*
void	PutAccessLog( unsigned char ch )
{
	if ( AccessRtBbsLogSw == YES )	*AccessRtBbsBufPtr++ = ch;
}
*/

static	void	WriteLog( int XoffSw )
{
	// XOFF を送信
	if ( XoffSw == YES )	SendChar( XOFF );
	// データを書き出す
	fwrite( AccessRtBbsBuf,1,AccessRtBbsBufPtr-AccessRtBbsBuf,CatlogFpo);
	// AccessRtBbsBufPtr の初期化
	AccessRtBbsBufPtr= AccessRtBbsBuf;
	// XON を送信
	if ( XoffSw == YES )	SendChar( XON );
}

static	int		isEscChar( int ch )
{
	if ( EscOn == YES ) {
		if (	ch != '[' 
		&&		ch != ';' 
		&&		( ! isdigit(ch) )
		)							EscOn = NO;
		return( YES );				// ESC 最後のコードを無視する
	} else if ( ch == ESC ) {
		EscOn = YES;
		return( YES );				// ESC の始まり
	};
	return( NO );
}

static	int		abortCheck()
{
	/* KEY_INPUT ROUTINE */
	moji = KYB_inpchk( &chrcnt, &encode );		/* キー入力チェック */
	if ( chrcnt > 0 ) {
		if ( moji == 0x8001 ) {					/* 'PF1' key */
			KYB_clrbuf( );
			return( YES );
		};
	};
	return( NO );
}

struct	CheckStr	{
			char	lastChar;
			char	*str;
};

static	char	waitTopChar[256]= 0;
static	char	waitLastChar[256]= 0;

static	const	char	*waitPtr[ 256 ]= NULL;

// wait の戻り値
//		0 : 時間切れの場合
//		数: 文字列の順
static	int		wait( clock_t duration, const char *ptr[] )
{
	unsigned	short	limit;			 /* 受信成功待ちループの最大値 */
				int		i, maxLen;
				int		ret;
				char	*ps;
	const		char	*pt;
				clock_t	start ;
				int		topCharSw;

	start		= clock( );
	duration	*= CLOCKS_PER_SEC;

	for ( i=0; i<256 ; i++ ) {
		waitTopChar[i] = waitLastChar[i] = 0;
	};

	for ( i=0, maxLen=0 ; ptr[i] != NULL ; i++ ) {
		pt= ptr[i];
		if ( *pt == '\n' ) {	waitTopChar[ CR ] = // waitTopChar[ LF ] = 
								1;
		} else {				waitTopChar[ *pt] = 1;
		};
		while( *pt ) pt++;
		ret= pt - ptr[i];				// len
		pt--;
		if ( *pt == '\n' ) {	// waitLastChar[ CR ] = 
								waitLastChar[ LF ] = 1;
		} else {				waitLastChar[ *pt] = 1;
		};
		waitPtr[i] = pt;				// ptr[i] の最後の文字
		if ( maxLen < ret )		maxLen = ret;
	};

	topCharSw= NO;
	AccessRtBbsChkBufPtr = AccessRtBbsChkBuf;
	forever {
		ret = 0;
		if ( clock( ) - start > duration )	break;
		if ( abortCheck() == YES )			break;

		ret = RSB_Read( RS232C_PORT, &leng );
		if ( leng <= 0 )					continue;

		for ( limit=0; limit < 0xffff; limit++ ) {
			ret = RSB_Receive(RS232C_PORT,&rdata,&status);
			if ( ret == 0 )		break;
		};
		if ( ret != 0 )						continue;
		putch( rdata );									// 全部画面に表示する
		if ( isEscChar( rdata ) == YES )	continue;	// ESCは読み飛ばす

		if ( AccessRtBbsLogSw == YES )	*AccessRtBbsBufPtr++ = rdata;

		if ( topCharSw == NO ) {
			if ( AccessRtBbsBufPtr >= AccessRtBbsBufMax )	WriteLog( YES );
			AccessRtBbsChkBufPtr = AccessRtBbsChkBuf;
		};

		*AccessRtBbsChkBufPtr++ = rdata;
		if ( AccessRtBbsChkBufPtr >= AccessRtBbsChkBufMax ) {
											return( 0 );
		};

		// 最初の文字と最後の文字は読み込んだか？
		if ( waitTopChar[ rdata ] != 0 )	topCharSw= YES;
		if ( topCharSw == NO )				continue;
		if ( waitLastChar[ rdata ] == 0 )	continue;

		// 入力文字列の一致チェック
		for ( i=0; ptr[i] != NULL ; i++ ) {
			pt = waitPtr[i];		// ptr[i] の最後の文字
			ret= i + 1;
			// 文字列の一致を後ろから調べる
			for ( ps= AccessRtBbsChkBufPtr-1 ; ptr[i] <= pt ; pt--, ps-- ) {
				// pt は '\n' だが ps は CR LF なので、その処理
				if ( *pt == '\n' ) {
					if ( *ps != LF ) {			ret= 0;		break;		};
					ps--;
					if ( *ps != CR ) {			ret= 0;		break;		};
				} else if ( *ps != *pt ) {		ret= 0;		break;		};
			};
			if ( ret != 0 )		goto waitJump;			// 一致！
		};
	};

waitJump:
	return( ret );
}

static	void	OutTimeOutErrorMes( char *mes )
{
	sprintf( YesNoMes, "\n時間切れで %s に失敗しました。", mes );
	WriteLog( YES );
	cputs( YesNoMes );		OutLog( YesNoMes );
}

static	void	OutErrorMes( char *mes )
{
	WriteLog( YES );
	sprintf( YesNoMes, "\nエラーで %s に失敗しました", mes );
	cputs( YesNoMes );		OutLog( YesNoMes );
}

/* ウェイト時間の設定 */
#define		Wtime1		  10	// モデム応答待ち時間
#define		Wtime2		  60
#define		Wtime3		  90
#define		Wtime5		 180	// RTBBS-NETプロンプト待ち時間
#define		Wtime4		  60	// select入力待ち時間
#define		WtimeD		3600	// ﾀﾞｳﾝﾛｰﾄﾞ終了待ち時間の限定

static	const	char	*WaitMKMes[] = {
		">",
		NULL
};
/*｢<｣を待つ共通処理*/
static	void	WaitMK()
{
	forever {
		switch ( wait( 5, WaitMKMes ) ) {
			case 0:		SendStr( "\n" );	break;
			case 1:							return;
		};
	};
};

static	const	char	*WaitMKBMes[] = {
		">",
		NULL
};
/*ﾎﾞｰﾄﾞ指定巡回で｢<｣を待つ共通処理*/
static	void	WaitMKB()
{
	forever {
		switch ( wait( Wtime5, WaitMKBMes ) ) {
			case 0:		SendStr( "\n" );	break;
			case 1:							return;
		};
	};
};

static	const	char	*retMAINMes[] = {
		"T,S,C,X,Y,G,Z,M,B,E,K,H,?,0,Q",
		",Q",
		"Q:Quit",
		"A,D,M,U,W,",
		"quit",
		"FILE",
		"?,0",
		"\n= MAIN =",
		"\n= MAIN =",
		"\nメイン",
		",O",
		"\nMAIN ",
		"\nMAIN ",
		"# ",
		",\\,?,",
		NULL
};
/*MAIN ﾒﾆｭｰに復帰する処理	*/
static	void	retMAIN()
{
	forever {
		switch ( wait( 3, retMAINMes ) ) {
			case 0:						SendStr("\n");			break;
			case 1:		WaitMK();		SendStr("0|Q\n");		break;
			case 2:		WaitMK();		SendStr("Q\n");			break;
			case 3:		WaitMK();		SendStr("Q\n");			break;
			case 4:		WaitMK();		SendStr("0\n");			break;
			case 5:		WaitMK();		SendStr("0\n");			break;
			case 6:		WaitMK();		SendStr("0|Q\n");		break;
			case 7:		WaitMK();		SendStr("0|Q\n");		break;
			case 8:		WaitMKB();		return;
			case 9:		WaitMKB();		return;
			case 10:	WaitMKB();		return;
			case 11:	WaitMKB();		return;
			case 12:	WaitMKB();		return;
			case 13:	WaitMKB();		return;
			case 14:	WaitMK();		SendStr("//|0|Q\n");	break;
			case 15:	WaitMKB();		return;
		};
	};
};

static	const	char	*PROwait2Mes1[] = {
		"write",
		",\\,#,?,0",
		"作成終了",
		"編集終了",
		"おわり",
		"自動署名を",
		NULL
};
static	const	char	*PROwait2Mes20[] = {
		"/N",
		">",
		NULL
};
static	const	char	*PROwait2Mes211[] = {
		"60",
		">",
		NULL
};
static	const	char	*PROwait2Mes2111[] = {
		"60",
		NULL
};
static	const	char	*PROwait2Mes212[] = {
		"quit",
		",?,0",
		"/N) >",
		NULL
};
static	const	char	*PROwait2Mes22[] = {
		",?,O",
		"[N]",
		NULL
};

static	char	docfile[ MAX_FILENAME_LEN ];

static	int		exFile( char *fileName )
{
	FILE	*fp;

	if ( ( fp = fopen( fileName, "r" ) ) == NULL )		return( NO );
	fclose( fp );
	return( YES );
}

static	int		PROwait2()
{
	int		sw;
	char	*mes;

	for ( sw= NO ; sw == NO ; ) {
		switch ( wait( 3, PROwait2Mes1 ) ) {
			case 0:		break;
			case 1:		WaitMK();		SendStr("W\n");		sw= YES;	break;
			case 2:		WaitMK();		SendStr("0|W\n");	sw= YES;	break;
			case 3:		WaitMK();		SendStr("0|W\n");	sw= YES;	break;
			case 4:		WaitMK();		SendStr("0|W\n");	sw= YES;	break;
			case 5:		WaitMK();		SendStr("0|W\n");	sw= YES;	break;
			case 6:		WaitMK();		SendStr("N|0|W\n");	sw= YES;	break;
			default:													break;
		};
	};

	for ( sw= NO ; sw == NO ; ) {
		switch ( wait( 3, PROwait2Mes20 ) ) {
			case 0:		SendStr( "\n" );	break;
			case 1:
				if ( exFile( docfile ) == YES ) {
					// CHeck = NO;
					WaitMK();		SendStr("Y\n");
					switch ( wait(Wtime2, PROwait2Mes211 ) ) {
						case 0:
							mes= "\nホストがおもいよ〜\n";
							cputs( mes );		OutLog( mes );
							return( NO );
						case 1:		break;		// 60
						case 2:		SendStr( "\n" );
							switch ( wait(Wtime2, PROwait2Mes2111 ) ) {
								case 0:		break;
								case 1:		break;
								default:	break;
							};
							break;
						default:	break;
					};
					if ( GetFileSize( docfile ) > 0 )	SendFile( docfile );
					SendStr( "\n//\n" );
					for ( sw= NO ; sw == NO ; ) {
						switch ( wait( 3, PROwait2Mes212 ) ) {
							case 1:	WaitMK();	SendStr( "\n" );
									sw= YES;	break;
							case 2:	WaitMK();	SendStr( "0|W\n" );
									sw= YES;	break;
							case 3:	SendStr( "N|0|W\n" );
									sw= YES;	break;
							default:			break;
						};
					};
					sw= NO;
				} else {	// exFile( docfile ) == NO
					SendStr( "N|0|Q\n" );
				};
			case 2:		SendStr( "0|Q\n" );
				switch( wait( 3, PROwait2Mes22 ) ) {
					case 0:		break;
					case 1:		break;
					case 2:		SendStr( "\n" );	break;
				};
				sw = YES;
			default:			break;
		};
	};
	return( YES );
};

static	const	char	*PROwait1Mes1[] = {
		"60",
		"これでよろしいですか？",
		NULL
};
static	const	char	*PROwait1Mes2[] = {
		"1|",
		NULL
};
/*	ﾌﾟﾛﾝﾌﾟﾄ終了待ち共通処理		*/
static	int		PROwait1( char *fileName )
{
	switch ( wait( Wtime5, PROwait1Mes1 ) ) {
		case 0:		break;
		case 1:		break;
		case 2:		SendStr( "\n" );	break;
	};
	switch ( wait( 3, PROwait1Mes2 ) ) {
		case 0:		SendFile( fileName );	break;
		case 1:		SendFile( fileName );	break;
	};
	SendStr( "\n//\n" );
	return( PROwait2() );
};

static	const	char	*PROwait3Mes[] = {
		"[RET]",
		",\\,#,?,0",
		"0:quit",
		NULL
};
static	void	PROwait3()
{
	forever {
		switch ( wait( 3, PROwait3Mes ) ) {
			case 1:	WaitMK();	SendStr("\n");			return;
			case 2:	WaitMK();	SendStr("0|0|Y\n");		return;
			case 3:	WaitMK();	SendStr("0|Y\n");		return;
		};
		retMAIN();
	};
};

static	const	char	*CHKcom1Mes[] = {
		"値が大きすぎ",
		"指定が間違って",
		"使用でき",
		"SELECT",
		"BOARD",
		"パスワードが違",
		",?,0",
		"既にこのメッセージにはレスポンスが有ります",
		"[Y]",
		NULL
};
static	int		CHKcom1( char *fileName, char *title )
{
	switch ( wait( Wtime2, CHKcom1Mes ) ) {
		case 1:	PROwait3();								break;
		case 2:	PROwait3();								break;
		case 3:	WaitMK();			SendStr("Q\n");		break;
		case 4:	WaitMK();			SendStr("Q\n");		break;
		case 5:	WaitMK();			SendStr("0|Q\n");	break;
		case 6:	WaitMK();			SendStr("Q\n");		break;
		case 7:	WaitMK();			SendStr("N\n");
				return( PROwait1( fileName ) );
		case 8:	WaitMK();			SendStr("E|");
				SendStr( title );	SendStr("\n");		SendStr("Y|N\n");
				return( PROwait1( fileName ) );
		case 9:	WaitMK();			SendStr("Y|N\n");
				return( PROwait1( fileName ) );
		default:										break;
	};
	return( YES );
};

static	const	char	*ApplyStartMes[] = {
		"(Y/[N]) >",
		"--- More --- (0:quit) >",
		NULL
};
static	const	char	*ApplyEndMes[] = {
		"([Y]/N) >",
		"--- More --- (0:quit) >",
		NULL
};

// アップファイルから緒データを入力し、サインアップを実行する
static	int		RtBbsApply( )
{
	FILE	*fpi;
	char	ctlFile[ MAX_FILENAME_LEN ];
	char	rsvFile[ MAX_FILENAME_LEN ];

	CopyWord( ctlFile, rtBbsTmp.path, MAX_FILENAME_LEN );
	append_yen( ctlFile );
	strcat( ctlFile, "UP\\SIGNUP" );
	strcpy( rsvFile, ctlFile );
	strcat( ctlFile, ".CTL" );		strcat( rsvFile, ".BAK" );
	remove( rsvFile );
	if ( ( fpi= fopen( ctlFile, "r" ) ) == NULL )			return( YES );
	fclose( fpi );

	SendStr( "A\n" );		// Apply コマンド
	// (Y/[N]) >
RtBbsApplyJump1:
	switch ( wait( Wtime2, ApplyStartMes ) ) {
		case 0:		break;
		case 1:		break;
		case 2:		SendStr( "\n" );
					goto		RtBbsApplyJump1;
		default:	break;
	};
	SendStr( "Y\n" );
	SendFile( ctlFile );

	// 以上でよろしいですか？([Y]/N) >
RtBbsApplyJump2:
	switch ( wait( Wtime2, ApplyEndMes ) ) {
		case 0:		break;
		case 1:		break;
		case 2:		SendStr( "\n" );
					goto		RtBbsApplyJump2;
		default:	break;
	};
	SendStr( "Y\n" );

	remove( rsvFile );
	// rename( old, New );
	rename( ctlFile, rsvFile );

	return( YES );
}

// ここで、発言をアップする
static	int		FORUMup()		// DORA からの関数名
{
	FILE	*fpi, *fpr;
	int		horyu;
	char	ctlFile[ MAX_FILENAME_LEN ];
	char	rsvFile[ MAX_FILENAME_LEN ];
	char	typ[ 20 ];
	char	title[ 80 ];
	char	fileName[ MAX_FILENAME_LEN ];

	CopyWord( ctlFile, rtBbsTmp.path, MAX_FILENAME_LEN );
	append_yen( ctlFile );
	strcat( ctlFile, "UP\\CATLOG2" );
	strcpy( rsvFile, ctlFile );
	strcat( ctlFile, ".CTL" );		strcat( rsvFile, ".RSV" );
	remove( rsvFile );
	if ( ( fpi= fopen( ctlFile, "r" ) ) == NULL )			return( YES );

	while( fgets( str, LINE, fpi ) != NULL ) {
		if ( analyzeFapxUpLine( str, typ, fileName, title, &horyu ) == NO ) {
			continue;
		};
		if ( horyu == YES ) {
			fpr= fopen( rsvFile, "a" );
			fputs( str, fpr );
			fclose( fpr );
			continue;
		};
		// ボード番号 MesNum 発言元 ComNum タイトル title 発言 fileName
		// でアップする
		if ( ComNum == 0 ) {
			sprintf( YesNoMes, "B#%d|E|%s\n", MesNum, title );
		} else {
			sprintf( YesNoMes, "B#%d|R|%d|%s\n", MesNum, ComNum, title );
		};
		SendStr( YesNoMes );
		if ( CHKcom1( fileName, title ) == NO ) {
			fclose( fpi );
			return( NO );
		};
	};
	fclose( fpi );

	remove( ctlFile );
	// rename( old, New );
	rename( rsvFile, ctlFile );

	return( YES );
}

static	int		openModem( int speed )
{
	int		ret;
	int		worki = 0;
	char	*mes;

	// 通信パラメータの設定
		WORD(buffer+0) = 4096;
		WORD(sbuffer+0) = 4096;
		BYTE(para+0) = 0x91;				// 拡張通信/8ビット/X制御あり
		switch( speed ) {
			case  2400:	ret = 0x03;		break;
			case  4800:	ret = 0x04;		break;
			case  9600:	ret = 0x05;		break;
			case 19200:	ret = 0x06;		break;
			default:	ret = 0x05;		break;
		};
		BYTE(para+1) = (char)ret;					/* bps	*/
		DWORD(para+2) = (unsigned int)buffer;		/* 受信バッファアドレス */
		WORD(para+6) = 0x14;						/* 受信バッファセレクタ */
		WORD(para+8) = 20;							/* 送信タイムアウト時間 */
		WORD(para+10) = 20;							/* 受信タイムアウト時間 */
		DWORD(para+12) = (unsigned int)RSBraddr;	/* 受信通知アドレス */
		WORD(para+16) = 0x000c;						/* 受信通知セレクタ */
		BYTE(para+18) = 0x08;						/* 拡張通信モード */
		BYTE(para+19) = 0;							/* XON コード */
		BYTE(para+20) = 0;							/* XOFF コード */
		DWORD(para+21) = (unsigned int)sbuffer;		/* 送信バッファアドレス */
		WORD(para+25) = 0x14;						/* 送信バッファセレクタ */

	// INPKEY INIT
		chrcnt=0;
		encode=0;

	// RS232C INIT
		ret = RSB_Init( );	/* または ret = RSB_Init2( ); */

	// RS232C_PORT CHECK
		worki = 0x01;
		worki = worki << RS232C_PORT;
		worki = worki & RSB_Chk( );
		if ( worki == 0 ) {
			mes = "\n指定のポートは接続されていません｡";
			cputs( mes );		OutLog( mes );
			return( NO );
		};

	// RS232C OPEN
		ret = RSB_Setpara(RS232C_PORT,para);
//		ret = RSB_Rdpara(RS232C_PORT,para);
		ret = RSB_Open(RS232C_PORT);

	// STATUS CHECK
		ret = RSB_Status(RS232C_PORT,&status,&serial);
		serial = serial & 0x22;
		if ( serial == 0 ) {
			mes = "\nシリアルポートの状態に異常があります｡";
			cputs( mes );		OutLog( mes );
			return( NO );
		};
		ret = RSB_Ctrl(RS232C_PORT,serial);

	// INIT STATUS
		ret = RSB_Initbuf(RS232C_PORT);
		ret = RSB_Clsxoff(RS232C_PORT);

	// RSB_Setint(RS232C_PORT,intbuf);
	// RSB_Rdint(RS232C_PORT,intbuf);

	// KEY INIT
		KYB_init( );
		KYB_clic(1);
		KYB_clrbuf( );

	RSB_Initbuf(RS232C_PORT);
	RSB_Clsxoff(RS232C_PORT);
}

static	int		closeModem()
{
	int		ret;

	KYB_clrbuf( );
	ret = RSB_Break(RS232C_PORT,10);
	/* ret = RSB_Dtr(1); */
	ret = RSB_Close(RS232C_PORT);
	ret = RSB_End( );

	return( ret );
}

static	int		dialone( char *telNum, int speed )
{
	char	*mes;

	openModem( speed );

//	sprintf( YesNoMes, "%s にダイヤルします", telNum );
//	cputs( YesNoMes );		OutLog( YesNoMes );

	if ( *telNum == '\0' || telNum == NULL )		return( NO );

	mes= "回線接続開始 モデム初期化第１ ";
	SendStr( "ATZ\n" );
	switch( wait( Wtime1, OkMes ) ) {
		case 0:		OutTimeOutErrorMes( mes );	return( NO );	// 時間切れ
		case 1:		break;										// 成功！
		case 2:		OutErrorMes( mes );			return( NO );	// エラー
		default:								return( NO );
	};

	mes= "回線接続開始 モデム初期化第２ ";
	SendStr( "ATH0Q0V1E1\n" );
	switch( wait( Wtime1, OkMes ) ) {
		case 0:		OutTimeOutErrorMes( mes );	return( NO );	// 時間切れ
		case 1:		break;										// 成功！
		case 2:		OutErrorMes( mes );			return( NO );	// エラー
		default:								return( NO );
	};

	mes= "回線接続開始 RT-BBS にダイヤル ";
	strcpy( str, "AT" );
	if ( *ModemKisyu != '\0' ) {
		mes= "回線接続開始 モデム初期化第３ ＋ RT-BBS にダイヤル ";
		strcpy( str, ModemCommand );
		if ( *str == '\0' ) {		strcpy( str, "AT" );
		};
	};
	strcat( str, "D" );
//	strcat( str, "P" );		// パルス回線
//	strcat( str, "T" );		// トーン回線
	strcat( str, telNum );		strcat( str, "\n" );
	SendStr( str );

	switch( wait( 80, ConnectMes ) ) {
		case 0:		// 時間切れ
			OutTimeOutErrorMes( mes );					return( NO );
		case 1:		break;								// 成功！
		case 2:		// BUSY
			mes= "\n回線がふさがっているので別の電話番号にかけなおします。";
			cputs( mes );		OutLog( mes );
			return( NO );
		case 3:		// NO CARRIER
			mes=	"\nキャリーを失ってしまいました。"
					"もう１度、電話番号をかけなおします。";
			cputs( mes );		OutLog( mes );
			return( NO );
		default:											return( NO );
	};
	return( YES );
}

static	int		MoveTopMenu()
{
	int		i;

	for ( i=0; i<3 ; i++ ) {
		switch ( wait( 10, BbsTopMenuMes ) ) {
			case 0:		// 時間切れ
				SendStr( "0|0|Q\n" );
				break;
			case 1:
			case 3:		// for DIGITAL-BBS
				return( YES );
			case 2:
				RtBbsExMoreSw= YES;
				SendStr( "\n" );
				break;
			default:							break;
		};
	};
	return( NO );
}

static	int		AccessRtBbsAutoMode( )
{
	char	*mes;
	int		ch;

ConnectYamaBbsJump:

	for ( ch=0; ch < 10 ; ch++ ) {
		if ( dialone( rtBbsTmp.tel1, rtBbsTmp.speed1 ) == YES )		break;
		closeModem();
		if ( dialone( rtBbsTmp.tel2, rtBbsTmp.speed2 ) == YES )		break;
		closeModem();
		if ( dialone( rtBbsTmp.tel3, rtBbsTmp.speed3 ) == YES )		break;
		closeModem();
		if ( dialone( rtBbsTmp.tel4, rtBbsTmp.speed4 ) == YES )		break;
		closeModem();
	};

	if ( ch >= 10 ) {
		mes= "ダイヤルに失敗しました。終了します。";
		cputs( mes );		OutLog( mes );
		return( YES );
	};

	mes= "ＩＤの入力 ";
	switch( wait( 40, IdMes ) ) {
		case 0:		OutTimeOutErrorMes( mes );	return( NO );	// 時間切れ
		case 1:		break;										// 成功！
		default:	break;
	};
/*
	mes= "ＩＤの入力２ ";
	switch( wait( 10, IdMes ) ) {
		case 0:		OutTimeOutErrorMes( mes );	return( NO );	// 時間切れ
		case 1:		break;										// 成功！
		default:	break;
	};
*/

	if ( *rtBbsTmp.id == '\0' ) {		return( NO );			// 以後 手動
	} else {
		SendStr( rtBbsTmp.id );			SendStr( "\n" );
		mes= "パスワードの入力 ";
		switch( wait( 15, UserPasswordMes ) ) {
			case 0:
				OutTimeOutErrorMes( mes );
				return( NO );
			case 1:		// 成功！
				SendStr( rtBbsTmp.passWord );		SendStr( "\n" );
			default:
				break;
		};
	};

	// サインアップを実行する
	if ( RtBbsApply() == NO )		return( NO );

	// ここで、発言をアップする
	// アップする間、ログ記録を止める(^^;)
	AccessRtBbsLogSw = NO;
	if ( FORUMup() == NO )			return( NO );
	AccessRtBbsLogSw = YES;

	if ( DownRtBbsBoadSw == NO )	goto BbsTopMenuMesJump;

	mes= "ボードのダウン ";
	if ( MoveTopMenu() == NO )						return( NO );
	SendStr( "BN|Y\n" );

DownBoadTopMenuMesJump2:
	switch ( wait( 2*60, DownBoadDateMes ) ) {
		case 0:		// 時間切れ
			OutTimeOutErrorMes( mes );
			return( NO );
		case 1:
		case 3:		// for DIGITAL-BBS
			SendStr( SayDate );
			SendStr( "\n" );
			break;
		case 2:
			RtBbsExMoreSw= YES;
			SendStr( "\n" );
			goto	DownBoadTopMenuMesJump2;
		default:	break;
	};

	mes= "ボードのダウン終了 ";
DownBoadMesJump:
	switch ( wait( 20*60, DownBoadEndMes ) ) {
		case 0:		// 時間切れ
			OutTimeOutErrorMes( mes );
			return( NO );
		case 1:
		case 3:		// for DIGITAL-BBS
			SendStr( "Q\n" );
			break;
		case 2:
			RtBbsExMoreSw= YES;
			SendStr( "\n" );
			goto	DownBoadMesJump;
		default:	break;
	};

BbsTopMenuMesJump:
	mes= "ログ・オフ ";
	switch ( wait( 20*60, BbsTopMenuMes ) ) {
		case 0:		// 時間切れ
			OutTimeOutErrorMes( mes );
			return( NO );
		case 1:
		case 3:		// for DIGITAL-BBS
			SendStr( "O\n" );
			break;
		case 2:
			RtBbsExMoreSw= YES;
			SendStr( "\n" );
			goto	BbsTopMenuMesJump;
		default:	break;
	};

BbsTopMenuMesJump2:
	mes= "ログ・オフ２ ";
	switch( wait( 10, LogOffMes ) ) {
		case 0:		// 時間切れ
//			OutTimeOutErrorMes( mes );
			SendStr( "0|0|Q\n" );
			goto	BbsTopMenuMesJump;
		case 1:
			SendStr( "Y\n" );
			break;
	};

	mes= "回線の切断 ";
	switch( wait( 20, DisConnectMes ) ) {
		case 0:		// 時間切れ
			OutTimeOutErrorMes( mes );
			SendStr( "0|0\n" );
			goto	BbsTopMenuMesJump;
		case 1:		break;
	};

	return( YES );
}

void	SetLineHelpAlert( char *mes );

int		AccessRtBbs( )
{
				int		ret ;
	unsigned	short	limit;			 /* 受信成功待ちループの最大値 */
				int		worki = 0;
				int		AccessRtBbsSw;

				char	*pWork, *ptr;
				FRAME	fr = { 0, 0, 639, 479 };
	extern		char	*guiEgbPtr ;	/*	EGB のワークアドレス	*/
				char	work[EgbWorkSize];
				char	*mes;

	////////////////////
	// イニシャライズ //
	////////////////////
	AccessRtBbsLogSw = YES;
	if ( CatlogFpo != NULL ) {
		fclose( CatlogFpo );	CatlogFpo= NULL;
	};
	CopyWord( FileName, rtBbsTmp.path, MAX_FILENAME_LEN );
	append_yen( FileName );
	check_and_make_output_path( FileName );
	SetToday();
	strcat( FileName, ToDay );
	strcat( FileName, ".LOG" );

	if ( (CatlogFpo = fopen( FileName , "ab" ) ) == NULL ) {
		sprintf( YesNoMes, "%s のログ・ファイルのオープン", rtBbsTmp.Name );
		er_open( FileName, 1, YesNoMes );
	};

	// Yama-BBS 以外にはアクセスできないようにする
	//		限定版
	if (	strcmp( rtBbsTmp.tel1, "0720-50-9412" ) != 0
	||		*rtBbsTmp.tel2 != '\0'
	||		*rtBbsTmp.tel3 != '\0'
	||		*rtBbsTmp.tel4 != '\0'
	) {
		SetLineHelpAlert(
"現在、Ｙａｍａ−ＢＢＳ以外にはアクセスできません。"
		);
		fclose( CatlogFpo );	CatlogFpo= NULL;
		return( NO );
	};

	// 入力バッファを確保する
	worki= TL_checkMemory( 1 ) * 4096;			// フリー・メモリーの容量
	if ( worki < 1024*1024*3 ) {
		SetLineHelpAlert(
			"メモリーが足りない（３Ｍバイト以上）ので通信できません"
		);
		fclose( CatlogFpo );	CatlogFpo= NULL;
		return( NO );
	};
	worki= worki / 3;
	// 受信バッファ
	AccessRtBbsBufPtr= AccessRtBbsBuf= TL_malloc( worki );
	if ( AccessRtBbsBuf == NULL ) {
		SetLineHelpAlert( "メモリーが足りない（？？？１）ので通信できません" );
		fclose( CatlogFpo );	CatlogFpo= NULL;
		return( NO );
	};
	AccessRtBbsBufMax = AccessRtBbsBuf + ( worki * 4 / 5 );
	// チェックバッファ
	AccessRtBbsChkBuf= TL_malloc( worki );
	if ( AccessRtBbsChkBuf == NULL ) {
		SetLineHelpAlert( "メモリーが足りない（？？？２）ので通信できません" );
		fclose( CatlogFpo );	CatlogFpo= NULL;
		return( NO );
	};
	AccessRtBbsChkBufMax = AccessRtBbsChkBuf + ( worki * 4 / 5 );

	// 画面情報を保存する
		/*	ファイルダイアログ関係の終了処理		*/
		/*	メモリ開放			*/
		FDG_FreeFileDlg( );
		FDG_RecovCurDir( );		// カレントディレクトリを復帰する
		// EGBのワークの退避
		if ( MG_pushEgbWork( guiEgbPtr, &pWork) <0 ) {
			error_bug( "メモリーが足りません guiEgbPtr" );
		};
		MG_mosDisp( 2 );					// マウスの消去
		ptr = MG_SaveRect( &fr );			// 画面の退避
	// システムの停止
		FM_ResetVector( );					// INT 23H/24H終了
		MMI_pauseSystem( );

	// consol を起動する
		EGB_init(work,EgbWorkSize);
		EGB_resolution(work,0,3);
		EGB_resolution(work,1,3);
		EGB_displayPage(work,1,3);

	// 高速文字列表示ライブラリーのスタート
		copen();

		sprintf( YesNoMes, "\n%s へのアクセスを開始します\n", rtBbsTmp.Name );
		cputs( YesNoMes );		OutLog( YesNoMes );

		rcnt=0;

		AccessRtBbsSw= YES;

	if ( AccessRtBbsAutoMode( ) == YES ) {
		goto	AccessYamaBbsJump1;
	};

	AccessRtBbsSw= NO;
	WriteLog( YES );
	mes = "\n手動通信を開始します。"
			"\n終了する場合は「ＰＦ１」キーを押して下さい。強制終了します。";
	cputs( mes );		OutLog( mes );

	for ( ; ; ) {		/* START TERM */
		ret = RSB_Read( RS232C_PORT, &leng );
		for ( ; leng > 0 ; leng-- ) {
			for ( limit=0; limit < 0xffff; limit++ ) {
				ret = RSB_Receive(RS232C_PORT,&rdata,&status);
				if ( ret == 0 )		break;
			};
			putch( rdata );
			if ( isEscChar( rdata ) != YES ) {
				*AccessRtBbsBufPtr++ = rdata;
				if ( AccessRtBbsBufPtr >= AccessRtBbsBufMax )	WriteLog(YES);
			};
		};

		/* KEY_INPUT ROUTINE */
		for( limit=0; limit < 0x0007; limit++ ) {
			moji = KYB_inpchk( &chrcnt, &encode );		/* キー入力チェック */
			if ( chrcnt > 0 ) break;
		};

		if ( chrcnt > 0 ) {
			if ( moji == 0x8001 ) {					/* 'PF1' key */
				goto	AccessYamaBbsJump1;
			};
			sdata = moji;
			SendChar( moji );
			chrcnt=0;
			KYB_clrbuf( );
		};
	};												/* END TERM */

	AccessRtBbsSw= NO;

	/* ENDING ROUTINE */
	WriteLog( NO );
	mes = "\n*** Program abnomal end ***\n";
	cputs( mes );		OutLog( mes );
	goto	AccessYamaBbsJump2;

AccessYamaBbsJump1:
	// 終了メッセージ
		sprintf(YesNoMes,
			"\n%s との通信を終了します(受信 %dbyte)",
			rtBbsTmp.Name,rcnt
		);
		cputs( YesNoMes );		OutLog( YesNoMes );
	closeModem();

AccessYamaBbsJump2:
	//////////////
	// 終了処理 //
	//////////////
	// 受信バッファの内容をファイルに書き出す
		WriteLog( NO );
	// 高速文字列表示ライブラリーの終了
		CON_close( );
	// 画面モードを復帰する
		EGB_resolution( guiEgbPtr, 0, 3 );
		EGB_resolution( guiEgbPtr, 1, 3 );

	// システムの再開
		MMI_continueSystem( );
		FM_SetVector( );					// INT 23H/24H設定
	// 画面情報を復帰する
		MG_popEgbWork( guiEgbPtr, pWork);	// EGBのワークの復帰
		MG_RecovRect( &fr, ptr, TRUE );		// 画面の復帰
		MG_mosDisp( 3 );					// マウスの表示
	// ファイルダイアログ関係の初期化処理
		FDG_SaveCurDir( );		/*	カレントディレクトリを保存する		*/
		FDG_InitFileDlg( );		/*	ファイルダイアログの初期化			*/

	// 通信バッファの解放
		TL_free( AccessRtBbsChkBuf );
		TL_free( AccessRtBbsBuf );

	// ログ・ファイルのクローズ
		if ( CatlogFpo != NULL ) {
			fclose( CatlogFpo );	CatlogFpo= NULL;
		};

		RtBbsWithOutQuit( FileName );

		AccessRtBbsLogSw = NO;

	return( AccessRtBbsSw );
}

static	void	RtBbsWithOutQuit( char *fileName )
{
	FILE	*fpi, *fpo;
	char	*p;
	char	bakFile[ MAX_FILENAME_LEN ];
	// 下の部分をカット
	char	*mes1  = "--- More --- (0:quit) >\r                       \r";

	if ( RtBbsExMoreSw == NO )				return;

	strcpy( bakFile, fileName );
	p= last_yen( bakFile );
	p= last_comma( p );
	if ( *p == '.' )		*p= '\0';
	strcat( bakFile, ".BAK" );
	remove( bakFile );
	// rename( old, New );
	rename( fileName, bakFile );
	if ( ( fpi= fopen( bakFile, "r" ) ) != NULL ) {
		if ( ( fpo = fopen( fileName, "w" ) ) == NULL ) {
			er_open( fileName, 1, "ログの書き出し" );
		};
		while( fgets( str, LINE, fpi ) != NULL ) {
			if ( matchstr( str, mes1 ) == YES ) {
				strcpy( str, str + strlen( mes1 ) );
			};
			fputs( str, fpo );
		};
		fclose( fpo );
		fclose( fpi );
	};
}

#endif	// CATLOG_EXG

#endif	// TMENU

/* DIVIDE_END */

/* DIVIDE_START=..\common.h */
/*	CATLOG の共通部分のヘッダ・ﾌｧｲﾙ	*/

#ifndef	COMMON_H
#define	COMMON_H	1

#define	RT_BBS_ACCESS_OK_SW_MES	"RT-BBS Access OK!:"

#include	<stdio.h>
#include	<stdlib.h>
#include	<ctype.h>
#include	<string.h>
#include	<errno.h>
#include	<time.h>
#include	<fcntl.h>
#include	<direct.h>

#ifndef		CATLOG_EXG
//	#include	<process.h>
#endif	// ! CATLOG_EXG

#include	<memory.h>
#include	<dos.h>			// for _dos_find*
#include	<io.h>

#ifdef	TMENU
#	ifdef	CATLOG_EXG
#		define		VERSION		"2.00y/T-OS/EXG"
#	else
#		define		VERSION		"2.00y/T-OS/EXP"
#	endif
#else
#		define		VERSION		"2.00y/Win"
#endif

#define		DEF_FILE_VERSION	1

#ifdef	TMENU
#define		DEF_FILE_NAME				"CATLOG2.DEF"	// 定義ファイル名
#define		SayLong				int
#else
#define		DEF_FILE_NAME				"CATLOG2W.DEF"	// 定義ファイル名
#define		SayLong				unsigned	short	int
#include	<windows.h>
#endif

#define		YES		1
#define		NO		-1
#define		CLEAR	0

#define		ON		1
#define		OFF		0

#define		CR		0x0d
#define		LF		0x0a

#define	ISKAN1	1
#define	ISKAN2	2

#ifdef	iskanji
    #undef iskanji
#endif

#ifdef	iskanji2
    #undef iskanji2
#endif

#define	iskanji(c)	(kantbl[(unsigned char)c]&ISKAN1)
#define	iskanji2(c)	(kantbl[(unsigned char)c]&ISKAN2)

#define	forever		for ( ; ; )

#define		FA_DIREC	0x10							// High-C にも無い定数

#define		LINE				(1024*8)
#define		MAX_FILENAME_LEN	128
#define		MAX_DIRS			256

/********************/
/* ファイル名の定義 */
/********************/
#define		IDX_FILE_NAME					"CATLOG2.IDX"	// ｲﾝﾃﾞｯｸｽ･ﾌｧｲﾙ
#define		DEL_FILE_TABLE_FILE_NAME		"CATLOG2.RMV"	// 削除ファイル名
#define		FORCE_DEL_FILE_TABLE_FILE_NAME	"CATLOG2.FRM"	// 削除ファイル名
#define		DL_FILE_NAME			"ＤＬ"			// DL の名前
#define		KAIGI_FILE_NAME			"会議室"		// 会議室の名前
#define		ID_HANDLE_FILE_NAME		"ＩＤ.TXT"
#define		TMP_FILE_NAME			"CATLOG.TMP"	// ﾃﾝﾎﾟﾗﾘｨ･ファイル名
#define		TMP2_FILE_NAME			"CATLOG2.TMP"	// ﾃﾝﾎﾟﾗﾘｨ･ファイル名
#define		ID_TMP_FILE_NAME		"CATLOG-I.TMP"	// ｢ＩＤ｣のtmp file 名
#define		TREE_TMP_FILE_NAME		"CATLOG%02d.TMP"	// ｺﾒﾝﾄﾂﾘｰのtmp file 名
#define		KAIGI_TMP_FILE_NAME		"CATLOG-K.TMP"	// ｢会議室｣のtmp file 名
#define		DL_TMP_FILE_NAME		"CATLOG-L.TMP"	// ｢ＤＬ｣のtmp file 名
#define		CATLOG_TIME_FILE_NAME	"CATLOGDT.TMP"	// 時刻調査用 tmp file
#define		BILL_FILE_NAME			"BILL.DAT"		// 課金情報のファイル名
#define		DONE_FILE_NAME			"CATLOG.DON"	// 実行済みのファイル名
#define		ALL_IN_1_MAIL_FILE_NAME	"NIFMAIL.TXT"	// 全てのﾒｰﾙを纏めたﾌｧｲﾙ名

struct	RtBbsData	{
			char	Name[ 40 ];
			char	DirName[ 12 ];
			char	path[ MAX_DIRS ];
			char	id[ 12 ];
			char	passWord[ 12 ];
			char	Handle[ 20 ];
			char	tel1[ 40 ];		int		speed1;
			char	tel2[ 40 ];		int		speed2;
			char	tel3[ 40 ];		int		speed3;
			char	tel4[ 40 ];		int		speed4;
			struct	RtBbsData	*next;
};

/*
	index file ファイルの構造
		0         1         2
		 123456789 123456789 123456789 1234
		nn lll YYMMDDHHMM NAA02244 dddddddd
			nn			: 会議室番号 ( -1:HP -2:MAIL )
			lll			: 発言番号
			YYMMDDHHMM	: 発言の年月日時分
			NAA02244	: ID番号
			dddddddd	: seek 位置
			ddd			: dddへのコメント
*/

//	#define	IDX_FILE_DATA_OUT	"%2d %5d %10s %-8s %8ld %5d\n"
//	#define	IDX_FILE_DATA		"%d%d%s%s%d%d"

// インデックスについて
					//    123456789 12
#define	IndexFileId		"CATLOG2 Index"
#define	IndexVersion	10

struct CatlogIndex {
			int		RtBbsSw;				// RT-BBSの発言データ？
			char	ForumName[ 10 ];		// フォーラム名
			int		MesNum;					// 会議室番号
			int		FileNum;				// 書き出したファイル番号
			SayLong	SayNum;					// 発言番号
			SayLong	ComNum;					// コメント元番号
			long	SayDate;				// 発言日時
			long	seek;					// Seek位置
			long	SaySize;				// 発言の大きさ
			long	SayId;					// 発言者ID→数値化
			int		SayLine;				// 発言の行数
			char	Handle[ 20 ];			// 発言者のハンドル
			char	Mes[ 44 ];				// 発言の標題
			char	kidoku;					// 既読スイッチ
			char	dummy[3];				// ダミーがいる？
};

struct	SaveSayData		{
			char	FileName[ MAX_FILENAME_LEN ];
			int		RtBbsSw;				// RT-BBSの発言データ？
			char	ForumName[ 10 ];
			int		MesNum;
			SayLong	SayNum;
			SayLong	ComNum;
			long	SayDate;					// 発言の日付
			long	SayId;						// 発言者のＩＤ
			char	ForumNameLine[ 82 ];		// フォーラム名の行
			char	ForumNameLineSub[ 80 ];
			char	Handle[ 20 ];				// 発言者のハンドル
			char	Mes[ 44 ];					// 発言の標題
			long	BStart;						// ファイル中の発言の位置
			long	BEnd;						// 発言の終了位置
			int		GStart;						// 発言の開始行
			int		GEnd;						// 　〃  修了行
			int		InyouSw;
};

struct	CommentTreeData	{
			char	ForumName[ 10 ];			// フォーラム名
			int		MesNum;						// 会議室番号
			SayLong	SayNum;						// 発言番号
			long	SayId;						// 発言者のＩＤ
			long	indexSeek;					// インデックスファイルでの位置
			int		Level;						// コメントのレベル
												// -1 : 会議室
												// -2 : フォーラム
			char	FileName[ MAX_FILENAME_LEN ];
			long	seek;						// Seek位置
			long	SaySize;					// 発言の大きさ
			int		SayLine;					// 発言の行数
			char	Handle[ 20 ];				// ハンドル
			char	Mes[ 108 ];					// コメツリの表示行
			char	Mes2[ 80 ];					// 発言の標題
};

struct	Collect_LIB	{
			char	forum[ 12 ];		/* フォーラム名 */
			int		lib_num;			/* LIB 番号 */
			char	line[ 82 ];			/* その行 */
};

struct	Lib_List	{
			char	New[ 88 ];
			char	old[ 88 ];
};

struct	SetWithoutSearchMesType	{
	int		*sw;
	char	*mes;
};

struct	ID_NAME	{
			long		id;			/* ID名(数値化) */
			char		name[ 17 ];	/* ハンドル */
			int			num;		/* 出てきた回数 */
};

struct	SayData		{
	int			DataType;				// データのタイプ
	int			ForumName1;				// 第１フォーラム名
		// 会議室の入口で ForumName2 と入れ替わるかも知れない
		// よって、フォーラム名のチェックは ForumName2 も同時に行うこと
	int			ForumName2;				// 第２フォーラム名(SubName)
		// フォーラムの入口で設定される
	int			MesNum;					// 会議室番号
	SayLong		SayNum;					// 発言番号
	SayLong		CardinalNum;			// 発言の基数
	long		SayDate;				// 発言日時
	long		seek;					// seek 位置 byte
	int			InyouSw;				// 引用部分である＝YES
};

struct	CATLOG	{
			long	date;		/* 日時 */
			SayLong	SayNum;		/* 発言番号 */
			SayLong	ComNum;		/* コメント番号 なければ０ */
			long	seek_ichi;	/* シーク位置 */
			char	ahure;		// コメントツリーのあふれ
	};

struct	InsideVar	{
			char	*Mes;			// 表示用メッセージ
			char	*Option;		// CATLOG2.DEF オプション名
			char	*insideVar;		// 内部変数名
			int		len;			// 内部変数の長さ
};

struct	InsideBoolSw	{
			char	*Mes;			// 表示用メッセージ
			char	*Option;		// CATLOG2.DEF オプション名
			int		*insideVar;		// 内部変数名
};

/* CATLOG の会議室番号の定義 */
#define	UNKNOWN		0			// 未定義の会議室
#define	HP			-1			// Home Party
#define	MAIL		-2			// 電子ﾒｰﾙ
#define	BILL		-3			// 利用料金情報
#define	COLLECT_ID	-4			// ＩＤ収集ファイル
#define	LIB			-5			// LIB の一覧
#define	COLLECT_LIB	-6			// IDによる LIB の収集ファイル
#define	ALL_MAIL	-7			// １つにまとめた MAIL ファイル
#define	PATIO		-8			// ＰＡＴＩＯ 
#define	CLIP		-9			// クリッピングサービス
#define	NEW			-10			// 「今週のお知らせ」
#define	MES			-11			// フォーラムの会議室
#define	FORUM_MES	-12			// フォーラムの会議室の一覧
#define	RTN			-13			// RTN リストである

#define		DELETE_SAY		(SayLong)0

// GUI 部分で定義している関数
void	PrintMessage( const char * );
void	showKakunin( const char *mes );
void	CATLOG_exit( int re );

#ifndef	_COMMON_H
#define	_COMMON_H

#ifdef	TMENU
#include	<snd.h>
#include	<winb.h>
#include	<te.h>
#include	<fntb.h>
#include	<gui.h>

#include	<egb.h>
#ifdef	CATLOG_EXG
#	include	<guidbg.h>
#endif	// CATLOG_EXG

#include	<fnt.h>
#include	<file_dlg.h>

#define	malloc	TL_malloc
#define	free	TL_free
#define	chdir	FM_SetCurrentDir
#define	mkdir	FM_CreateDir
#define	rmdir	FM_RemoveDir

// _dos_findfirst を定義する
#ifdef	TMENU
#	define	FirstFile(f,FA)		FM_SearchFirstFile(f,FA)
#	define	NextFile			FM_SearchNextFile()
#	define	ATTR				ffblk.atr
#else
#	define	FirstFile(f,FA)		_dos_findfirst( f, FA, &ffblk )
#	define	NextFile			_dos_findnext( &ffblk );
#	define	ATTR				ffblk.attrib
#endif

extern	void	to_shift_zen_s( const char *src , char *targ );

#else	// VC++ の場合

#endif

#ifndef		CATLOG_EXG
#include	<process.h>
#endif		// ! CATLOG_EXG

struct	SrchFile	{
			char	*fileName;			// ファイル名 matchstr2 形式
			int		*sw;				// あったかどうかのスイッチ
};

// 定数の定義
#define		MAX_KAIGISHITSU		100
#define		MES_MODE			1
#define		FORUM_MODE			2
#define		FORUM_IN_MODE		3

// common*.c での変数の定義
#ifdef	COMMON_MAIN

#ifdef	VERIFY
			int		verify = NO;
#endif	/* VERIFY */

			int		exitFuncRet= ILLEGAL_FUNCTION;

	struct	RtBbsData	*pRtBbsData = NULL;
	struct	RtBbsData	rtBbsTmp;

			int		CheckRtBbsLogSw = NO;

			char	Version[ 40 ];
			char	ToDay[ 16 ];	/* 今日の年月日 */

			int		ForceWriteCatlogDefFileSw = NO;

			char	CatlogDefFileName[ MAX_FILENAME_LEN ];
			char	Catlog2ExecDir[ MAX_FILENAME_LEN ];	// 起動ディレクトリ
			char	FAPXDir[ MAX_FILENAME_LEN ];
			char	CatlogMesFileName[ MAX_FILENAME_LEN ];
			char	EditorCommand[ MAX_FILENAME_LEN ];
//			char	LhaCommand[ MAX_FILENAME_LEN ];
			char	PastInyouMoji[ 20 ];		//	ペーストの際の引用記号
			char	MyHandle[ 20 ];
//			char	YamaBbsId[ 10 ];
//			char	YamaBbsPassWord[ 10 ];
//			char	YamaBbsTelNumber[ 40 ];
			char	ModemKisyu[ 40 ];					// モデムの機種
			char	ModemCommand[ 40 ];					// モデムのコマンド
//			char	RtBbsDir[ MAX_FILENAME_LEN ];		// ログ保存ディレクトリ
//			char	YamaBbsLogDir[ MAX_FILENAME_LEN ];	// ログ保存ディレクトリ
			char	RtBbsRootDir[ MAX_FILENAME_LEN ];	// ログ保存ディレクトリ
			char	TmpDir[ MAX_FILENAME_LEN ];
			char	OutDir[ MAX_FILENAME_LEN ];
			char	IndexDir[ MAX_FILENAME_LEN ];

			char	DLDir[ MAX_FILENAME_LEN ];
			char	InDir[ MAX_DIRS ];
			char	UpDir[ MAX_FILENAME_LEN ];

			char	SearchFile[ MAX_DIRS ];
			char	WithoutSearchFile[ MAX_DIRS ];
			char	SearchID[ MAX_DIRS ];

			char	SearchStartDate[ 20 ];
			char	SearchEndDate[ 20 ];

			char	WithoutSearchMesType[ MAX_DIRS ];

			// スイッチ類
			int		CatlogAutoRunSw = NO;		// NO  : 自動実行しない
			int		CatlogAutoEndSw = NO;		// NO  : 自動終了しない
			int		YamaBbsAccessOkSw = NO;		// NO  : 許可しない
			int		ChangeCatlog1to2Index = 0;	// 0   : 未変更
			int		DefFileVersion = 0;			// 0   : 未変更
			int		Display = YES;				// YES : 表示する
			int		IndexModeSw= YES;			// YES : フォーラム毎
			int		NewFileSw= YES;				// YES : x001で新ﾌｧｲﾙを作る
			int		MakeNewFileSmallSw= NO;		// NO  : より小さな発言番号
			int		Mail1Sw= NO;				// NO  : ID毎のﾌｧｲﾙ
			int		DeleteOldFileSw= NO;		// NO  : 削除しない
			int		StoreLZHSw= NO;				// NO  : 格納しない
			int		ReStoreLZHSw= NO;			// NO  : 解凍しない
			int		OutSoundMes= NO;			// NO  : 音を出さない
			// CatlogFindfirst で サブディレクトリを検索する
			int		CatlogFindfirstSearchDirSw = YES;
			int		MaxCatlogFileSize ;
			int		MaxSeisyoLineSize = 64;

			char	FileName[ MAX_FILENAME_LEN ];
			char	FileNameSub[ MAX_FILENAME_LEN ];

			char	str[ LINE + 2 ];

			char	delimitter[6] = { 0x20, 0x08, 0x0d, 0x0a, '\0' };

			char	*WithoutAttr[58] = {
				// プログラム関係
				"BAT",	"COM",	"EXE",	"EXP",	"EXG",	"BAS",	"REX",	"DLL",
				"ASM",	"C",	"H",	"OBJ",	"O",	"A",	"LIB",	"LNK",
				"GUR",	"GUS",
					// 以上 18個
				// データ
				"BDF",	"ISH",	"LZH",	"WUP",
					// 以上 4個
				// 音楽関係
				"SND",	"PMB",	"FMB",	"MML",
					// 以上 4個
				// MopTerm
				"PLP",	"PLT",	"MAP",
					// 以上 3個
				// FAPX が作るデータ
				"SEA",	"NPB",	"RES",	"BML",	"CTL",	"WRK",	"SGN",	"PRF",
				"PRM",	"RTN",	"TMP",	"BAK",	"NEW",	"OLD",	"MSG",	"MEN",
					// 以上 16個
				// その他のデータ
				"GGG",	"ITM",
					// 以上 2個
				// CT が作るデータ
				"$A0",	"$B0",	"$C0",	"$H0",	"$I0",	"$L0",	"$L1",	"$M0",
				"$P0",	"$N0",
					// 以上 10個
				NULL
					// 以上 1個
				// 合計 58個
			};

			char	kantbl[]	= {
					0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
					0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
					0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
					0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
					2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
					2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
					2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
					2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,
					2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
					3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
					2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
					2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
					2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
					2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
					3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
					3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0
			};

struct	InsideVar	InsideVar[] =	{
	// 検索指定
	{	"ＦＡＰＸがあるディレクトリ",			"FAPX:",
		FAPXDir,			MAX_FILENAME_LEN
	},
	{	"入力ディレクトリ(*)",					"InDir:",
		InDir,				MAX_DIRS
	},
	{	"検索するファイル",						"SDir:",
		SearchFile,			MAX_DIRS
	},
	{	"検索しないファイル or ディレクトリ",	"WDir:",
		WithoutSearchFile,	MAX_DIRS
	},
	{	"検索するＩＤ",							"SID:",
		SearchID,			MAX_DIRS
	},
	{	"検索開始日時",							"SDate:",
		SearchStartDate,	20
	},
	{	"検索終了日時",							"EDate:",
		SearchEndDate,		20
	},
	{	"検索しない発言の種類",					"SType:",
		WithoutSearchMesType,		MAX_DIRS
	},
	// 出力指定
	{	"出力ディレクトリ(*)",					"OutDir:",
		OutDir,				MAX_FILENAME_LEN
	},
	{	"ＤＬのリストを出力するディレクトリ",	"DlDir:",
		DLDir,				MAX_FILENAME_LEN
	},
	{	"インデックスのディレクトリ",			"IndexDir:",
		IndexDir,			MAX_FILENAME_LEN
	},
	{	"ＴＭＰディレクトリ",					"TmpDir:",
		TmpDir,				MAX_FILENAME_LEN
	},
	{	"ハンドル",								"MyHandle:",
		MyHandle,			20
	},
	{	"ＲＴ−ＢＳＢのログ保存ルート・ディレクトリ",	"RT-BBS RootDir:",
		RtBbsRootDir,							MAX_FILENAME_LEN
	},
	{	"接続モデムの機種",						"MODEM:",
		ModemKisyu,			40
	},
	{	"接続モデムのコマンド",					"MODEM-Command:",
		ModemCommand,		40
	},
	// その他
	{	"ＣＡＴＬＯＧのメッセージ保存ファイル",	"CMes:",
		CatlogMesFileName,	MAX_FILENAME_LEN
	},
	{	"エディタの起動コマンド",				"Editor:",
		EditorCommand,		MAX_FILENAME_LEN
	},
//	{	"ＬＨＡの起動コマンド",					"LHA:",
//		LhaCommand,			MAX_FILENAME_LEN
//	},
	{	"ペーストの際の引用記号",				"PastInyou:",
		PastInyouMoji,		20
	},
	{	"ＦＡＰＸのアップ・ディレクトリ  → 内部データ（変更しないで下さい）",
		"UpDir:",
		UpDir,				MAX_FILENAME_LEN
	},
	{	NULL,	NULL,	NULL,	0	}
};

struct	InsideBoolSw	InsideBoolSw[] = {
	{	"ディレクトリ毎にインデックスを作る",
											"IDXMode:",	&IndexModeSw		},
	{	"x001で新ファイルを作る",			"NEWF:",	&NewFileSw			},
	{	"より小さな発言番号で新ファイルを作る",
											"NEWFS:",	&MakeNewFileSmallSw	},
	{	"ＭＡＩＬを１つにまとめる",			"MAIL1:",	&Mail1Sw			},
	{	"今日より古い生ﾛｸﾞ･ﾌｧｲﾙを削除する",	"DelOldLog:",&DeleteOldFileSw	},
	{	"生ﾛｸﾞ･ﾌｧｲﾙをLZHファイルに保存する","LzhU:",	&StoreLZHSw			},
	{	"LZH ﾌｧｲﾙからも発言を検索する",		"LzhE:",	&ReStoreLZHSw		},
	{	"内部状態を表示する",				"DISP:",	&Display			},
	{	"音声メッセージ",					"Sound:",	&OutSoundMes		},
	{	"自動実行する",						"AutoRun:",	&CatlogAutoRunSw 	},
	{	"自動終了する",						"AutoEnd:",	&CatlogAutoEndSw 	},
	{	"RT-BBSへのアクセス許可",			RT_BBS_ACCESS_OK_SW_MES,
											&YamaBbsAccessOkSw 				},
	{	NULL,								NULL,		NULL				}
};

struct	InsideBoolSw	InsideIntData[] = {
	{	"整理後ファイルの最大サイズ",
			"MaxLogSize:",					&MaxCatlogFileSize				},
	{	"清書した時の１行の文字数",
			"MaxSeisyoLineSize:",			&MaxSeisyoLineSize				},
		// ↓ CATLOG1 のｲﾝﾃﾞｯｸｽから CATLOG2 のｲﾝﾃﾞｯｸｽに変更したかのスイッチ
	{	"インデックスのバージョン → 内部データ（変更しないで下さい）",
			"IndexVersion:",				&ChangeCatlog1to2Index 			},
	{	"定義ファイルのバージョン → 内部データ（変更しないで下さい）",
			"DefVersion:",					&DefFileVersion		 			},
	{	NULL,								NULL,		NULL				}
};

			char	*CPDS;
			char	*LLSP, *LSP, *PSP, *NSP;
			int		LLSL, LSL, PSL, NSL;
			long	pool_seek_ichi;	/* ファイルの中での位置 */
			int		PoolGyou;				// 行数

	// 第３段階を実行するかどうかの内部スイッチ
			int		CheckMainCatlogMainSw= YES;
			// インデックス整理の最古の発言日時
			long	ArrangeIndexDataOldestDate;

			struct	SaveSayData	saveSayData;

			char	ForumName[ 10 ];		// フォーラム名
//			char	RtBbsName[ 10 ];		// RT-BBS名
			char	ForumNameLine[ 82 ];	// フォーラム名の行
			int		LibNum;					// ライブラリー番号
			char	HyoudaiLine[ 84 ];
			char	*Hyoudai;
			int		FapxLogMode = 1;
			int		MesNum;						/* 会議室番号 */
			int		lib_number;
			SayLong	SayNum;						/* 発言番号 */
			SayLong	ComNum;						/* コメント元番号 */
			char	Handle[ 20 ];				// 発言者のハンドル
			char	SayDate[ 24 ];				/* 発言の日付 */
			char	SayId[ 12 ];				/* 発言者のＩＤ */
			char	ForumName2[ 20 ];			/* 第２フォーラム名 */
			char	ForumNameLineSub[ 80 ];
			char	MesNumberLine[ 1024 ];		/* 会議室番号の行 */
			char	KNL[ MAX_KAIGISHITSU ][82];	// 会議室名の行
			char	DL_name[ MAX_KAIGISHITSU ][ 82 ];
			long	BStart;						// ファイル中の発言の位置
			long	BEnd;						// 発言の終了位置
			int		InyouSw= NO;
			/* 検索しないスイッチ */
			int		WithoutHPSaySw = NO;
			int		WithoutMESSaySw = NO;
			int		WithoutMAILSaySw = NO;
			int		WithoutLIBSaySw = NO;
			int		WithoutBILLSaySw = NO;
			int		WithoutPATIOSaySw = NO;
			int		WithoutCLIPSaySw = NO;
			int		DeleteDeletedSaySw = NO;
			FILE	*CatlogFpi=NULL , *CatlogFpo=NULL;
			int		CheckAbortSw= NO;
			int		CollectFileNumber = 0;
			int		HatsugenSu;
			int		AllHatsugenSu = 0;
			long	CollectFileSize = 0L;
			int		ForceDeleteOldFileSw= NO;
			int		CheckAndMakeCatlog2IndexSw= NO;
			int		SearchIdSayMainSw= NO;
			char	SaveSayDataFileName[ MAX_FILENAME_LEN ];
			char	YesNoMes[ 1024 ];

			int		ExistBillSw;			// BILL
			int		ExistMailSw;			// MAIL
			int		ExistHPSw;				// HP
			int		ExistPATIOSw;			// PATIO
			int		ExistCLIPSw;			// CLIP
			int		ExistFRAVSw;			// FRAV の会議室
			int		ExistFRAVLibSw;			// FRAV の LIB
			int		ExistFTOWNS1Sw;			// FTOWNS1 の会議室
			int		ExistFTOWNS1LibSw;		// FTOWNS1 の LIB
			int		ExistFTOWNS2Sw;			// FTOWNS2 の会議室
			int		ExistFTOWNS2LibSw;		// FTOWNS2 の LIB
			int		ExistFORUMSw;			// Forum Say
			int		ExistFORUMLibSw;		// LIB
			int		ExistCollectSaySw;		// Collect Say
			int		ExistCollectLibSw;		// Collect Lib

			struct	SrchFile	SrchFile[17] = {
				{	"BILL.$BL",		&ExistBillSw		},	// BILL
				{	"*.$MA",		&ExistMailSw		},	// MAIL
				{	"*.$HP",		&ExistHPSw			},	// HP
				{	"*.$PA",		&ExistPATIOSw		},	// PATIO
				{	"CLIP.$CP",		&ExistCLIPSw		},	// CLIP
				{	"FRAV.$F?",		&ExistFRAVSw		},	// FRAV の会議室
				{	"FRAV.$LB",		&ExistFRAVLibSw		},	// FRAV の LIB
				{	"FTOWNS1.$F?",	&ExistFTOWNS1Sw		},	// FTOWNS1 の会議室
				{	"FTOWNS1.$LB",	&ExistFTOWNS1LibSw	},	// FTOWNS1 の LIB
				{	"FTOWNS2.$F?",	&ExistFTOWNS2Sw		},	// FTOWNS2 の会議室
				{	"FTOWNS2.$LB",	&ExistFTOWNS2LibSw	},	// FTOWNS2 の LIB
				{	"*.$F?",		&ExistFORUMSw		},	// Forum Say
				{	"*.$??",		&ExistFORUMSw		},	// Forum Say
				{	"*.$LB",		&ExistFORUMLibSw	},	// LIB
				{	"*.$CS",		&ExistCollectSaySw	},	// Collect Say
				{	"*.$CL",		&ExistCollectLibSw	},	// Collect Lib
				{	NULL,			NULL				}	// データの終わり
			};

#else	// COMMON_MAIN

#ifdef	VERIFY
	extern	int		verify ;
#endif	/* VERIFY */

	extern	int		exitFuncRet;

	extern	struct	RtBbsData	*pRtBbsData ;
	extern	struct	RtBbsData	rtBbsTmp;

	extern	int		CheckRtBbsLogSw ;
	extern	char	Version[ 40 ];
	extern	char	ToDay[ 16 ];	/* 今日の年月日 */

	extern	int		ForceWriteCatlogDefFileSw ;

	extern	char	CatlogDefFileName[ MAX_FILENAME_LEN ];
	extern	char	Catlog2ExecDir[ MAX_FILENAME_LEN ];	// 起動ディレクトリ
	extern	char	FAPXDir[ MAX_FILENAME_LEN ];
	extern	char	CatlogMesFileName[ MAX_FILENAME_LEN ];
	extern	char	EditorCommand[ MAX_FILENAME_LEN ];
//	extern	char	LhaCommand[ MAX_FILENAME_LEN ];
	extern	char	PastInyouMoji[ 20 ];		//	ペーストの際の引用記号
	extern	char	MyHandle[ 20 ];
//	extern	char	YamaBbsId[ 10 ];
//	extern	char	YamaBbsPassWord[ 10 ];
//	extern	char	YamaBbsTelNumber[ 40 ];
	extern	char	ModemKisyu[ 40 ];					// モデムの機種
	extern	char	ModemCommand[ 40 ];					// モデムのコマンド
//	extern	char	RtBbsDir[ MAX_FILENAME_LEN ];		// ログ保存ディレクトリ
//	extern	char	YamaBbsLogDir[ MAX_FILENAME_LEN ];	// ログ保存ディレクトリ
	extern	char	RtBbsRootDir[ MAX_FILENAME_LEN ];	// ログ保存ディレクトリ
	extern	char	TmpDir[ MAX_FILENAME_LEN ];
	extern	char	OutDir[ MAX_FILENAME_LEN ];
	extern	char	IndexDir[ MAX_FILENAME_LEN ];

	extern	char	DLDir[ MAX_FILENAME_LEN ];
	extern	char	InDir[ MAX_DIRS ];
	extern	char	UpDir[ MAX_DIRS ];

	extern	char	SearchFile[ MAX_DIRS ];
	extern	char	WithoutSearchFile[ MAX_DIRS ];
	extern	char	SearchID[ MAX_DIRS ];

	extern	char	SearchStartDate[ 20 ];
	extern	char	SearchEndDate[ 20 ];

	extern	char	WithoutSearchMesType[ MAX_DIRS ];

			// スイッチ類
	extern	int		CatlogAutoRunSw ;		// NO  : 自動実行しない
	extern	int		CatlogAutoEndSw ;		// NO  : 自動終了しない
	extern	int		YamaBbsAccessOkSw ;		// NO  : 許可しない
	extern	int		ChangeCatlog1to2Index ;	// 0   : 未変更
	extern	int		DefFileVersion ;		// 0   : 未変更
	extern	int		Display ;
	extern	int		IndexModeSw;			// YES : フォーラム毎
	extern	int		NewFileSw;				// YES : x001で新ﾌｧｲﾙを作る
	extern	int		MakeNewFileSmallSw ;	// NO  : より小さな発言番号
	extern	int		Mail1Sw;				// NO  : ID毎のﾌｧｲﾙ
	extern	int		DeleteOldFileSw;		// NO  : 削除しない
	extern	int		StoreLZHSw;				// NO  : 格納しない
	extern	int		ReStoreLZHSw;			// NO  : 解凍しない
	extern	int		OutSoundMes ;			// NO  : 音を出さない
	extern	int		MaxCatlogFileSize ;
	extern	int		MaxSeisyoLineSize ;

			// 内部処理の為の広域変数
	extern	char	ForumName[ 10 ];		// フォーラム名
//	extern	char	RtBbsName[ 10 ];		// RT-BBS名
	extern	char	ForumNameLine[ 82 ];	// フォーラム名の行
	extern	int		MesNum;					// 会議室番号
	extern	int		LibNum;					// ライブラリー番号
	extern	int		HatsugenSu;
	extern	int		StartMesSw;
	extern	int		OverIdxSw ;
	extern	long	SearchFileSize ;
//	extern	FILE	*CATLOG_fpi, *CATLOG_fpo ;

			// CatlogFindfirst で サブディレクトリを検索する
	extern	int		CatlogFindfirstSearchDirSw ;

			// 発言検索の為のデータ
	extern	int		LineNumber;
	extern	long	sayDate;
	extern	char	HyoudaiLine[ 84 ];
	extern	char	*Hyoudai;

	extern	char	FileName[ MAX_FILENAME_LEN ];
	extern	char	FileNameSub[ MAX_FILENAME_LEN ];

	extern	char	str[ LINE + 2 ];
	extern	char	delimitter[6] ;
	extern	char	*WithoutAttr[58];
	extern	char	kantbl[256];
	extern	struct	InsideVar	InsideVar[] ;
	extern	struct	InsideBoolSw	InsideBoolSw[] ;
	extern	struct	InsideBoolSw	InsideIntData[] ;

	extern	char	*CPDS;
	extern	char	*LLSP, *LSP, *PSP, *NSP;
	extern	int		LLSL, LSL, PSL, NSL;
	extern	long	pool_seek_ichi;	/* ファイルの中での位置 */
	extern	int		PoolGyou;				// 行数


			// 第３段階を実行するかどうかの内部スイッチ
	extern	int		CheckMainCatlogMainSw ;
			// インデックス整理の最古の発言日時
	extern	long	ArrangeIndexDataOldestDate;

	extern	struct	SaveSayData	saveSayData;

	extern	char	ForumName[ 10 ];		// フォーラム名
	extern	char	ForumNameLine[ 82 ];	// フォーラム名の行
	extern	int		LibNum;					// ライブラリー番号
	extern	char	HyoudaiLine[ 84 ];
	extern	int		FapxLogMode ;
	extern	int		MesNum;						/* 会議室番号 */
	extern	int		lib_number;
	extern	SayLong	SayNum;						/* 発言番号 */
	extern	SayLong	ComNum;						/* コメント元番号 */
	extern	char	Handle[ 20 ];				// 発言者のハンドル
	extern	char	SayDate[ 24 ];				/* 発言の日付 */
	extern	char	SayId[ 12 ];				/* 発言者のＩＤ */
	extern	char	ForumName2[ 20 ];			/* 第２フォーラム名 */
	extern	char	ForumNameLineSub[ 80 ];
	extern	char	MesNumberLine[ 1024 ];		/* 会議室番号の行 */
	extern	char	KNL[ MAX_KAIGISHITSU ][82];	// 会議室名の行
	extern	char	DL_name[ MAX_KAIGISHITSU ][ 82 ];
	extern	long	BStart;						// ファイル中の発言の位置
	extern	long	BEnd;						// 発言の終了位置
	extern	int		InyouSw;
			/* 検索しないスイッチ */
	extern	int		WithoutHPSaySw ;
	extern	int		WithoutMESSaySw ;
	extern	int		WithoutMAILSaySw ;
	extern	int		WithoutLIBSaySw ;
	extern	int		WithoutBILLSaySw ;
	extern	int		WithoutPATIOSaySw ;
	extern	int		WithoutCLIPSaySw ;
	extern	int		DeleteDeletedSaySw ;
	extern	FILE	*CatlogFpi , *CatlogFpo ;
	extern	int		CheckAbortSw ;
	extern	int		CollectFileNumber ;
	extern	int		HatsugenSu;
	extern	int		AllHatsugenSu ;
	extern	long	CollectFileSize ;
	extern	int		ForceDeleteOldFileSw ;
	extern	int		CheckAndMakeCatlog2IndexSw ;
	extern	int		SearchIdSayMainSw ;
	extern	char	SaveSayDataFileName[ MAX_FILENAME_LEN ];
	extern	char	YesNoMes[ 1024 ];

	extern	int		ExistBillSw;			// BILL
	extern	int		ExistMailSw;			// MAIL
	extern	int		ExistHPSw;				// HP
	extern	int		ExistPATIOSw;			// PATIO
	extern	int		ExistCLIPSw;			// CLIP
	extern	int		ExistFRAVSw;			// FRAV の会議室
	extern	int		ExistFRAVLibSw;			// FRAV の LIB
	extern	int		ExistFTOWNS1Sw;			// FTOWNS1 の会議室
	extern	int		ExistFTOWNS1LibSw;		// FTOWNS1 の LIB
	extern	int		ExistFTOWNS2Sw;			// FTOWNS2 の会議室
	extern	int		ExistFTOWNS2LibSw;		// FTOWNS2 の LIB
	extern	int		ExistFORUMSw;			// Forum Say
	extern	int		ExistFORUMLibSw;		// LIB
	extern	int		ExistCollectSaySw;		// Collect Say
	extern	int		ExistCollectLibSw;		// Collect Lib

	extern	struct	SrchFile	SrchFile[17] ;
//	extern	char	*WithoutFileName[] ;

#endif	// COMMON_MAIN

//
// マクロ定義
//
#define	GET_LINE	if ( catlog_fgets( ) == NULL ) return
#define	GET_LINE2	if ( catlog_fgets( ) == NULL )

/* 処理の途中経過について */
#define	mess_check	if ( Display == YES ) 

/* 外部宣言の関数群 */
#define	IfMatchStrYes(s)		if(matchstr(PSP,s)==YES)
#define	matchPSP(form)	matchstr( PSP, form )
#define	matchNSP(form)	matchstr( NSP, form )

#define	BILL_SECOND_LINE1	"　年月　　回数　　時間 (分) 　アクセス料金　サーチャージ　　料金合計 (円)"
#define	BILL_SECOND_LINE2	"年/月   回数  時間 (分)     基本料金 (円)       追加料金 (円)     料金合計 (円)"
#define	BILL_SECOND_LINE3	"利用年月                 |    %%年%%月     |    %%年%%月     |    %%年%%月    "
#define	NO_BILL_MES		"月は課金データがありません"


/*******************************/
/* common.c で定義している関数 */
/*******************************/
void	SpawnTree( const char *mes );
void	collect_system( char *Command );
void	CheckAbort();
int		CheckMainLoop( const char *inDir );		// ..\common.c
void	CheckMainCatlogMain();					// ..\common.c

void	set_index_file_name( char *fileName, char *forumName );
void	check_and_make_output_path( const char *path );

void	CatlogFindFirst(
	const char *path,
	void (*sub)( const char *file, const char *ff_name )
);
void	CatlogFindFirst2(
	const char *path,
	void (*sub)( const char *file )
);

int		CheckMain( const char *inDir );
int		SetOptions( const char *option );
int		ReadCatlogDef( const char *DefFileName );
int		WriteCatlogDef( const char *DefFileName );
void	InitialInsideVars();
int		GetVarLen( char *var );
char	*GetVarMes( char *var );
void	SearchIdSayMain( const char *path );
void	CheckAndMakeCatlog2Index( int firstRunSw );
void	ArrangeIndexData( const char *inDir );
void	SearchIdNameMain( const char *out_file );	// ID ハンドル表作成

// 整理済ファイルから会議室の内容を表す文字列を抽出し、ファイルに書き出す。
int		GetKaigiName( const char *path, int startSw );
int		MakeTreeMain( const char *fileName );
// インデックスから fileNum のデータを削除する
void	DeleteIndexData( char *forumName, int mesNum, int fileNum );

/*********************************/
/* common_a.c で定義している関数 */
/*********************************/
char	*CopyWord( char *trg, char *src, int len );
void	CalcLineColum( char *mes, int *line, int *colum, int maxColum );
char	*KanStrCpy( char *trg, char *src, int klen );
int		analyzeFapxUpLine(char *line, char *typ, char *fileName, char *title, int *horyu );
int		MakeNewFapxResFileName( char *fileName, char *forumName );
int		GetSubDirName( const char *path, const char *tmpFile );
void	CheckAndSetForumNameData( char *forumName, int mesNum );
void	set_file_name( char *fileName, char *forum, int mesNum, int count );
int		GetCatlogFileNum( const char *f_name );
void	EraseLastSpace( char *str );
void	error_return( char *mes );
int		isFAPXfile( const char *name );
int		isLIBLine( );
int		isCLIPLine( const char *psp );
int		isCLIPFirstLine( const char *psp );
int		isLIBFirstLine( const char *psp );
int		isHpHyoudaiLine( const char *psp );
int		isBillFirstLine( const char *psp );
int		isMailFirstLine( const char * psp, const char *nsp );
int		isMesHyoudaiLine( const char *psp, const char *nsp );
int		isMesForumNameLine( const char *psp );
int		isMtlinkInputLine( const char *psp, const char *nsp );
int		isMesInputLine( const char *psp, const char *nsp );
int		isIDname( const char *str );
void	error_open_file( char *function_name );
long	date_to_long( char *date );
void	long_to_date( char *date , long d );
void	present_str_print();
void	last_str_copy( char *str );
void	present_str_copy( char *str );
void	next_str_copy( char *str );
void	catlog_fprintf( const char *targ );
size_t	catlog_fwrite();
void	end_check_pool();
char	*catlog_fgets();
int		initial_check_pool( const char *fileName );
int		mallocIdxSub( long max0, long size0, char **idx );	// ..\common_a.c
int		matchstr( const char *trg , const char *form );
int		matchstr2( const char *trg, const char *form );
char	*skip_space( const char *str );
char	*skip_digit( const char *p );
void	append_yen( char *trg );
char	*last_yen( const char *str );
char	*last_comma( const char *str );
void	without_crlf( char *str );
char	*touppers( char *p );				/* 文字列を大文字に変換する */
void	StrCut( char *p1, int max );
char	*CopyAlnum8( char *trg, const char *src );
char	*SkipAlnum8( char *src );
void	SetTmpDir( char *fileName );
void	SetTmpDirFile( char *trg, const char *add );
long	GetFileSize( const char *fileName );
int		FileCopy( const int mesNum, const char *fileName, long start, long end, FILE *fpo);
void	FileCopyEnd();
void	SetToday( );

/*********************************/
/* common_c.c で定義している関数 */
/*********************************/
long	Id2Long( char *id );
void	Long2Id( char *trg, long id );
void	checkSetSayDate( int typ, const char *ptr );
int		isWithoutSearchFile( const char *f_name, const char *ff_name );
int		isCATLOGFile( const char *f_name );
void	Check1File( const char *file, const char *name );

void	AccessYamaBbsOk( int sw );			// yamabbs.c

/*********************************/
/* common_r.c で定義している関数 */
/*********************************/
void	SaveRtBbsName( FILE *fpo );
void	SaveRtBbsName2( );
int		isRtBbsName( char *name );
int		isRtBbsName2( char *name );
void	SetRtBbsListMenuSub( );
void	SetRtBbsListMenu( char *option );
void	OutDoraData( const char *tmp );
void	OutDoraData2( const char *tmp );
int		SetRtBbsDoraData( const char *name );
void	OutModemMaker( );
int		OutModemKisyu( const char *Maker );
void	getModemPara( char *trg, char *ModemKisyu );
int		AccessRtBbs( );

// 外部関数		VC++ では必ず定義しておくこと
	int		get_yesno( char *message );
	void	error_end( );
	void	error_bug( const char *mes );
	void	er_open( const char *file, int mode, char *mes );

#endif	// _COMMON_H
#endif	// COMMON_H
/* DIVIDE_END */

/* DIVIDE_START=..\common_r.h */
// ..common_r.c へのヘッダー
//		他からは読み込まないこと

#ifndef	CATLOG_EXG

#define		RS232C_PORT		0		// 接続ポートは０で行う
#define		RS_BUF_SIZE		65536	// バッファのサイズ
#define		ESC				0x1b

#ifdef	COMMON_R

static	const	char	*OkMes[]		= { "OK\n",		"ERR",		NULL };
static	const	char	*ConnectMes[]	= {
				"CONNECT",
				"BUSY",
				"NO CARRIER",
				NULL
};
static	const	char	*IdMes[]		= {
				 "User ID  = ",
				 NULL
};
static	const	char	*UserPasswordMes[]		= {
				"Password =",
				NULL
};
static	const	char	*DownBoadEndMes[]	= {
				"A,L,N,S,H,?,Q) >",
				"--- More --- (0:quit) >",
				"A,L,N,S,H,T,W,?,Q) >",		// for DIGITAL-BBS
				NULL
};
static	const	char	*BbsTopMenuMes[]	= {
				"U,V,W,X,#,\\,?,O) >",
				"--- More --- (0:quit) >",
				"T,U,V,W,#,\\,?,O) >",		// for DIGITAL-BBS
				NULL
};
static	const	char	*DownBoadDateMes[]	= {
				"NEWS :日付指定 ([RET]:news) >",
				"--- More --- (0:quit) >",
				" ([RET]:News) >",			// for DIGITAL-BBS
				NULL
};
static	const	char	*LogOffMes[]	= {
				"(Y/[N]) >",
				NULL
};
static	const	char	*DisConnectMes[]	= {
				"--- Disconnected ---",
				NULL
};

static	char para[30];						// RSパラメータ
static	char buffer[RS_BUF_SIZE + 16 ];		// 受信バッファ
static	char sbuffer[RS_BUF_SIZE + 16 ];	// 送信バッファ
static	unsigned int status, serial;
static	unsigned int moji = '?';
static	int sdata = '?';
static	int rdata = '?';
static	int leng;
static	int rcnt;

static	int			chrcnt;
static	unsigned	encode;

#endif	COMMON_R

#endif	// CATLOG_EXG
/* DIVIDE_END */

