Artifact Content

Not logged in

Artifact 6032eb8a0710b17d3d86d2bfc0f56ae5fbd0aaa2


     1  
     2  #include "stdafx.h"
     3  #include "ArcB2e.h"
     4  #include "resource.h"
     5  #include "NoahApp.h"
     6  
     7  //----------------- ArcB2eクラス全体的な処理 ------------------------------
     8  
     9  char CArcB2e::st_base[MAX_PATH];
    10  int  CArcB2e::st_life=0;
    11  CArcB2e::CB2eCore* CArcB2e::rvm=NULL;
    12  
    13  const char* CArcB2e::init_b2e_path()
    14  {
    15  	kiPath dir( kiPath::Exe );
    16  	ki_strcpy( st_base, dir+="b2e\\" );
    17  	return st_base;
    18  }
    19  
    20  CArcB2e::CArcB2e( const char* scriptname ) : CArchiver( scriptname )
    21  {
    22  	st_life++;
    23  	exe = NULL;
    24  	m_LstScr = m_DcEScr = m_EncScr =
    25  	m_DecScr = m_SfxScr = m_LoadScr= m_ScriptBuf = NULL;
    26  }
    27  
    28  CArcB2e::~CArcB2e()
    29  {
    30  	if( !(--st_life) )
    31  		delete rvm;
    32  	delete [] m_ScriptBuf;
    33  }
    34  
    35  //------------------- スクリプト側にあまり関係しない部分 -------------------------
    36  
    37  bool CArcB2e::v_ver( kiStr& str )
    38  {
    39  	if( !exe )
    40  		return false;
    41  	exe->ver( str );
    42  
    43  	kiStr tmp;
    44  	for( int i=0,e=m_subFile.len(); i<e; ++i )
    45  	{
    46  		str += "\r\n";
    47  		CArcModule(m_subFile[i]).ver( tmp );
    48  		str += tmp;
    49  	}
    50  	return true;
    51  }
    52  
    53  bool CArcB2e::v_check( const kiPath& aname )
    54  {
    55  	return exe ? exe->chk( aname ) : false;
    56  }
    57  
    58  int CArcB2e::v_contents( const kiPath& aname, kiPath& dname )
    59  {
    60  	return exe ? exe->cnt( aname, dname ) : aUnknown;
    61  }
    62  
    63  //------------------- スクリプトを読み込み&eval( load: ) -------------------
    64  
    65  bool CArcB2e::load_module( const char* name )
    66  {
    67  	exe = new CArcModule( name, m_usMode );
    68  	return exe->exist();
    69  }
    70  
    71  int CArcB2e::v_load()
    72  {
    73  	//-- 拡張スクリプトファイルを開く
    74  	kiStr fname( st_base ); fname += mlt_ext();
    75  	kiFile fp;
    76  	if( fp.open( fname ) )
    77  	{
    78  		//-- ファイル全体を読み込み
    79  		unsigned int ln=fp.getSize();
    80  		m_ScriptBuf = new char[ ln+1 ];
    81  		ln = fp.read( (unsigned char*)m_ScriptBuf, ln );
    82  		m_ScriptBuf[ ln ] = '\0';
    83  
    84  		//-- section毎に切り分ける
    85  		bool pack1,chk=false;
    86  		for( char* p=m_ScriptBuf; *p; p++ )
    87  		{
    88  			switch( *p )
    89  			{
    90  			case 'c': case 'd': case 'e': case 'l': case 's':
    91  				if( ki_memcmp(p,"load:",5) )
    92  					*p='\0', m_LoadScr = (p+=4)+1;
    93  				else if( ki_memcmp(p,"encode:",7) )
    94  					*p='\0', m_EncScr = (p+=6)+1, pack1=false;
    95  				else if( ki_memcmp(p,"encode1:",8) )
    96  					*p='\0', m_EncScr = (p+=7)+1, pack1=true;
    97  				else if( ki_memcmp(p,"decode:",7) )
    98  					*p='\0', m_DecScr = (p+=6)+1;
    99  				else if( ki_memcmp(p,"sfx:",4) )
   100  					*p='\0', m_SfxScr = (p+=3)+1, m_SfxDirect=false;
   101  				else if( ki_memcmp(p,"sfxd:",5) )
   102  					*p='\0', m_SfxScr = (p+=4)+1, m_SfxDirect=true;
   103  				else if( ki_memcmp(p,"check:",6) )
   104  					*p='\0', (p+=5), chk=true;
   105  				else if( ki_memcmp(p,"decode1:",8) )
   106  					*p='\0', m_DcEScr = (p+=7);
   107  				else if( ki_memcmp(p,"list:",5) )
   108  					*p='\0', m_LstScr = (p+=4);
   109  			}
   110  			while( *p && *p!='\n' && *p!='\r' )
   111  				p++;
   112  			if( *p=='\0' )
   113  				break;
   114  		}
   115  
   116  		//-- [load:]を実行!
   117  		if( m_LoadScr )
   118  		{
   119  			//-- RythpVM 起動
   120  			if( !rvm )
   121  				rvm = new CB2eCore;
   122  
   123  			//-- 初期化
   124  			m_Result=0;
   125  			rvm->setPtr( this,mLod );
   126  
   127  			//-- 実行
   128  			rvm->eval( m_LoadScr );
   129  
   130  			//-- 結果
   131  			if( m_Result==0 )
   132  				return (m_DecScr?aMelt|(m_DcEScr?aList|aMeltEach:0)|(chk?aCheck:0):0)
   133  					 | (m_EncScr?aCompress|(pack1?0:aArchive)|(m_SfxScr?aSfx:0):0);
   134  		}
   135  	}
   136  	return 0;
   137  }
   138  
   139  int CArcB2e::exec_script( const char* scr, scr_mode mode )
   140  {
   141  	//-- 初期化
   142  	m_Result = 0;
   143  	rvm->setPtr( this, mode );
   144  
   145  	//-- 実行
   146  	char* script = new char[ki_strlen(scr)+8];
   147  	ki_strcpy( script, "(exec " );
   148  	ki_strcat( script, scr );
   149  	ki_strcat( script, ")" );
   150  	rvm->eval( script );
   151  	delete [] script;
   152  
   153  	//-- 結果
   154  	return m_Result;
   155  }
   156  
   157  //-------------------- リストアップ eval( list: ) -----------------------
   158  
   159  bool CArcB2e::v_list( const arcname& aname, aflArray& files )
   160  {
   161  	//-- スクリプト無しで何とかできるならする。
   162  	if( !exe )
   163  		return false;
   164  	else if( exe->isdll() )
   165  		return exe->lst_dll( aname, files );
   166  	else if( !m_LstScr )
   167  		return false;
   168  
   169  //-- リスティングスクリプトに必要なデータ
   170  
   171  	// 書庫名
   172  	m_psArc = &aname;
   173  	// ファイルリスト
   174  	m_psAInfo = &files;
   175  
   176  //-- 実行! ---------------------
   177  
   178  	return 0==exec_script( m_LstScr, mLst );
   179  }
   180  
   181  //-------------------- 展開処理 eval( decode: ) -----------------------
   182  
   183  int CArcB2e::v_melt( const arcname& aname, const kiPath& ddir, const aflArray* files )
   184  {
   185  //-- 解凍スクリプトに必要なデータ
   186  
   187  	// カレント
   188  	::SetCurrentDirectory( ddir );
   189  	// 書庫名
   190  	m_psArc = &aname;
   191  	// 出力先ディレクトリ
   192  	m_psDir = &ddir;
   193  	// ファイルリスト
   194  	m_psAInfo = files;
   195  
   196  //-- 実行! ---------------------
   197  
   198  	return exec_script( files ? m_DcEScr : m_DecScr,
   199  						files ? mDc1     : mDec );
   200  }
   201  
   202  //-------------------- 圧縮処理 eval( encode: sfx: ) -----------------------
   203  
   204  int CArcB2e::cmpr( const char* scr, const kiPath& base, const wfdArray& files, const kiPath& ddir, const int method )
   205  {
   206  //-- 圧縮スクリプトに必要なデータ
   207  
   208  	arcname aname(
   209  		ddir,
   210  		files[0].cAlternateFileName,
   211  		files[0].cFileName );
   212  	int mhd=method+1;
   213  
   214  	// カレント
   215  	::SetCurrentDirectory( base );
   216  	// 書庫名
   217  	m_psArc = &aname;
   218  	// ベースディレクトリ
   219  	m_psDir = &base;
   220  	// メソッド
   221  	m_psMhd = &mhd;
   222  	// リスト
   223  	m_psList = &files;
   224  
   225  //-- 実行! --------------------
   226  
   227  	return exec_script( scr, mEnc );
   228  }
   229  
   230  bool CArcB2e::arc2sfx( const kiPath& temp, const kiPath& dest )
   231  {
   232  //-- SFX変換スクリプトに必要なデータ
   233  
   234  	kiFindFile f;
   235  	WIN32_FIND_DATA fd;
   236  	kiPath wild( temp );
   237  	f.begin( wild += "*" );
   238  	if( !f.next( &fd ) )
   239  		return false;
   240  	kiPath from, to, oldname( fd.cFileName );
   241  	arcname aname( temp, fd.cAlternateFileName[0] ? fd.cAlternateFileName : fd.cFileName, fd.cFileName );
   242  
   243  	// カレント
   244  	::SetCurrentDirectory( temp );
   245  	// 書庫名
   246  	m_psArc = &aname;
   247  	// ディレクトリ
   248  	m_psDir = &temp;
   249  
   250  //-- 実行! ----------------------
   251  
   252  	if( 0x8000<=exec_script( m_SfxScr, mSfx ) )
   253  		return false;
   254  
   255  //-- コピー ----------------------
   256  
   257  	bool skipped=false, ans=false;
   258  	f.begin( wild );
   259  	while( f.next( &fd ) )
   260  	{
   261  		if( !skipped && oldname == fd.cFileName ) // テンポラリ書庫はコピーしない。
   262  		{
   263  			skipped=true;
   264  			continue;
   265  		}
   266  		from = temp, from += fd.cFileName;
   267  		to   = dest, to   += fd.cFileName;
   268  		if( ::CopyFile( from, to, FALSE ) )
   269  			ans = true;
   270  	}
   271  	return ans;
   272  }
   273  
   274  int CArcB2e::v_compress( const kiPath& base, const wfdArray& files, const kiPath& ddir, int method, bool sfx )
   275  {
   276  	const char* theScript = m_EncScr;
   277  
   278  	if( sfx )
   279  	{
   280  		if( m_SfxDirect )
   281  			theScript = m_SfxScr;
   282  		else
   283  		{
   284  			kiPath tmp;
   285  			myapp().get_tempdir( tmp );
   286  
   287  			// テンポラリへ圧縮
   288  			int ans = cmpr( m_EncScr, base, files, tmp, method );
   289  			if( ans < 0x8000 )
   290  				// テンポラリに落ちてるファイルをSFXに変換&コピー!
   291  				ans = (arc2sfx( tmp, ddir ) ? 0 : 0x8020);
   292  
   293  			// カレントを戻しておかないと削除できない…(;_;)
   294  			::SetCurrentDirectory( base );
   295  			tmp.remove();
   296  			return ans;
   297  		}
   298  	}
   299  
   300  	// 出力先へ普通に圧縮
   301  	return cmpr( theScript, base, files, ddir, method );
   302  }
   303  
   304  //-----------------------------------------------------------------//
   305  //-------------------- RythpVMの方の実務 --------------------------//
   306  //-----------------------------------------------------------------//
   307  
   308  bool CArcB2e::CB2eCore::exec_function( const kiVar& name, const CharArray& a, const BoolArray& b, int c, kiVar* r )
   309  {
   310  	bool processed = false;
   311  
   312  	if( m_mode==mLod ){ //**ロード時専用functions****************************
   313  		if( name=="name" ){
   314  			processed=true;
   315  
   316  			//---------------------------//
   317  			//-- (name module_filename)--//
   318  			//---------------------------//
   319  			if( c>=2 )
   320  			{
   321  				x->m_usMode = false;
   322  				if( c>=3 )
   323  				{
   324  					getarg( a[2],b[2],&t );
   325  					x->m_usMode = ( t=="us" );
   326  				}
   327  
   328  				getarg( a[1],b[1],&t );
   329  				if( x->load_module(t) )
   330  					*r = "exec";
   331  				else
   332  					*r = "", x->m_Result=0xffff;
   333  			}
   334  
   335  		}else if( name=="type" ){
   336  			processed=true;
   337  
   338  			//-----------------------------------//
   339  			//-- (type ext method1 method2 ...)--//
   340  			//-----------------------------------//
   341  			for( int i=1; i<c; i++ )
   342  			{
   343  				getarg( a[i],b[i],&t );
   344  				if( i==1 )
   345  					x->set_cmp_ext( t );
   346  				else
   347  				{
   348  					const char* ptr=t;
   349  					x->add_cmp_mhd( *ptr=='*' ? ptr+1 : ptr, *ptr=='*' );
   350  				}
   351  			}
   352  		}else if( name=="use" ){
   353  			processed=true;
   354  
   355  			//-------------------------------//
   356  			//-- (use module1 module2 ...) --//
   357  			//-------------------------------//
   358  			for( int i=1; i<c; i++ )
   359  			{
   360  				getarg( a[i],b[i],&t );
   361  				x->m_subFile.add( t );
   362  			}
   363  		}
   364  	}else{//************ ロード時には使えないfunctions *********************
   365  		if( ki_memcmp( (const char*)name, "arc", 3 ) ){
   366  			processed=true;
   367  
   368  			//---------------------------//
   369  			//-- (arc[+-].xxx [slfrd]) --//
   370  			//---------------------------//
   371  			arc( ((const char*)name)+3, a, b, c, r );
   372  
   373  		}else if( ki_memcmp( (const char*)name, "list", 4 ) ){
   374  			processed=true;
   375  
   376  			//----------------------------//
   377  			//-- (list[\*|\*.*] [slfn]) --//
   378  			//----------------------------//
   379  			list( ((const char*)name)+4, a, b, c, r );
   380  
   381  		}else if( name=="method" ){
   382  			processed=true;
   383  
   384  			//-------------------//
   385  			//-- (method [no]) --//
   386  			//-------------------//
   387  			if( c>=2 )
   388  			{
   389  				getarg( a[1],b[1],&t );
   390  				*r = t.getInt()==*x->m_psMhd ? "1" : "0";
   391  			}
   392  			else
   393  				r->setInt( *x->m_psMhd );
   394  
   395  		}else if( name=="dir" ){
   396  			processed=true;
   397  
   398  			//-----------//
   399  			//-- (dir) --//
   400  			//-----------//
   401  			*r = (x->m_psDir ? *x->m_psDir : (const char*)"");
   402  
   403  		}else if( name=="del" ){
   404  			processed=true;
   405  
   406  			//-------------------//
   407  			//-- (del filenam) --//
   408  			//-------------------//
   409  			if( c>=2 )
   410  			{
   411  				getarg( a[1],b[1],&t );
   412  				::DeleteFile( kiPath( t.unquote() ) );
   413  			}
   414  
   415  		}else if( ki_memcmp( (const char*)name, "resp", 4 )
   416  			||	  ki_memcmp( (const char*)name, "resq", 4 ) ){
   417  			processed=true;
   418  
   419  			//----------------------------//
   420  			//-- (resp[@|-o] (list a)) ---//
   421  			//----------------------------//
   422  			resp( name[3]=='p', ((const char*)name)+4, a, b, c, r );
   423  
   424  		}else if( name=="cd" ){
   425  			processed=true;
   426  
   427  			//-------------------//
   428  			//-- (cd directory)--//
   429  			//-------------------//
   430  			if( c>=2 )
   431  			{
   432  				getarg( a[1],b[1],&t );
   433  				::SetCurrentDirectory( t.unquote() );
   434  			}
   435  
   436  		}else if( name=="cmd" || name=="xcmd" ){
   437  			processed=true;
   438  
   439  			//----------------------------//
   440  			//-- (cmd command line ...)---//
   441  			//-- (xcmd command line ...)--//
   442  			//----------------------------//
   443  			if( name[0]=='x' && c<2 )
   444  				x->m_Result = 0xffff;
   445  			else
   446  			{
   447  				CArcModule* xxx = x->exe;
   448  				kiVar       cmd;
   449  				int         i=1;
   450  
   451  				if( name[0] == 'x' )
   452  				{
   453  					kiVar mm;
   454  					getarg( a[i],b[i],&mm );
   455  					i++;
   456  					xxx = new CArcModule( mm, x->m_usMode );
   457  				}
   458  				for( ; i<c; i++ )
   459  					getarg( a[i],b[i],&t ), cmd+=t, cmd+=' ';
   460  
   461  				bool m = (mycnf().miniboot() || m_mode==mDc1);
   462  				x->m_Result = xxx->cmd( cmd, m );
   463  				r->setInt( x->m_Result );
   464  
   465  				if( name[0] == 'x' )
   466  					delete xxx;
   467  			}
   468  		}else if( name=="scan" || name=="xscan" ){
   469  			processed=true;
   470  
   471  			//----------------------------------------//
   472  			//-- (scan BL BSL EL SL dx cmd...) -------//
   473  			//-- (xscan BL BSL EL SL dx CMD cmd...) --//
   474  			//----------------------------------------//
   475  			if( c<6 || (name[0]=='x'&&c<7) )
   476  				x->m_Result = 0xffff;
   477  			else
   478  			{
   479  				CArcModule* xxx = x->exe;
   480  
   481  				kiVar BL, EL;
   482  				getarg( a[1],b[1],&BL );
   483  				getarg( a[2],b[2],&t );
   484  				int BSL = t.getInt();
   485  				getarg( a[3],b[3],&EL );
   486  				getarg( a[4],b[4],&t );
   487  				int SL = t.getInt();
   488  				getarg( a[5],b[5],&t );
   489  				int dx = t.getInt();
   490  
   491  				int i=6;
   492  				if( name[0] == 'x' )
   493  				{
   494  					kiVar mm;
   495  					getarg( a[i],b[i],&mm );
   496  					i++;
   497  					xxx = new CArcModule( mm, x->m_usMode );
   498  				}
   499  
   500  				kiVar cmd;
   501  				for( ; i<c; ++i )
   502  					getarg( a[i],b[i],&t ), cmd+=t, cmd+=' ';
   503  
   504  				x->m_Result = xxx->lst_exe(
   505  					cmd, *const_cast<aflArray*>(x->m_psAInfo),
   506  					BL, BSL, EL, SL, dx ) ? 0 : -1;
   507  
   508  				if( name[0] == 'x' )
   509  					delete xxx;
   510  			}
   511  		}else if( name=="input" ){
   512  			processed=true;
   513  
   514  			//-------------------------//
   515  			//-- (input MSG DEFUALT) --//
   516  			//-------------------------//
   517  			kiVar msg, defval;
   518  			if( c>=2 )
   519  				getarg( a[1],b[1],&msg );
   520  			if( c>=3 )
   521  				getarg( a[2],b[2],&defval );
   522  			input( msg, defval, r );
   523  		}else if( name=="size" ){
   524  			processed=true;
   525  
   526  			//---------------------//
   527  			//-- (size FILENAME) --//
   528  			//---------------------//
   529  			if( c>=2 )
   530  			{
   531  				kiVar fnm;
   532  				getarg( a[1],b[1],&fnm );
   533  				r->setInt( kiFile::getSize( fnm.unquote() ) );
   534  			}
   535  		}else if( name=="is_file" ){
   536  			processed=true;
   537  
   538  			//---------------------//
   539  			//-- (is_file) --------//
   540  			//---------------------//
   541  			if( c==1 )
   542  				*r = (x->m_psList->len()==1
   543  					  && !kiSUtil::isdir( (*x->m_psList)[0].cFileName )) ? "1" : "0";
   544  		}else if( name=="is_folder" ){
   545  			processed=true;
   546  
   547  			//---------------------//
   548  			//-- (is_folder) ------//
   549  			//---------------------//
   550  			if( c==1 )
   551  				*r = (x->m_psList->len()==1
   552  					  && kiSUtil::isdir( (*x->m_psList)[0].cFileName )) ? "1" : "0";
   553  		}else if( name=="is_multiple" ){
   554  			processed=true;
   555  
   556  			//---------------------//
   557  			//-- (is_multiple) ----//
   558  			//---------------------//
   559  			if( c==1 )
   560  				*r = x->m_psList->len()>1 ? "1" : "0";
   561  		}else if( name=="find" ){
   562  			processed=true;
   563  
   564  			//---------------------//
   565  			//-- (find FILENAME) --//
   566  			//---------------------//
   567  			if( c>=2 )
   568  			{
   569  				kiVar fnm;
   570  				getarg( a[1],b[1],&fnm );
   571  				char buf[MAX_PATH];
   572  				if( 0==::SearchPath( NULL,fnm.unquote(),NULL,MAX_PATH,buf,NULL ) )
   573  					*r = "";
   574  				else
   575  					*r = buf, r->quote();
   576  			}
   577  		}
   578  	}
   579  
   580  	return processed ? true : kiRythpVM::exec_function(name,a,b,c,r);
   581  }
   582  
   583  void CArcB2e::CB2eCore::arc( const char* opt, const CharArray& a, const BoolArray& b,int c, kiVar* r )
   584  {
   585  	//---------------------------//
   586  	//-- (arc[+-].xxx [slfrd]) --//
   587  	//---------------------------//
   588  
   589  	// デフォルトオプション設定
   590  	const char* anm=x->m_psArc->lname;
   591  	enum{ full, nam, dir } part=full;
   592  	if( m_mode==mSfx )	part=nam; // sfx
   593  
   594  	// 指定があれば上書
   595  	if( c>=2 )
   596  	{
   597  		getarg( a[1],b[1],&t );
   598  		for( const char* p=t; *p; p++ )
   599  			switch(*p)
   600  			{
   601  			case 's': anm=x->m_psArc->sname; break;
   602  			case 'l': anm=x->m_psArc->lname; break;
   603  			case 'f': part=full; break;
   604  			case 'n': part=nam;  break;
   605  			case 'd': part=dir;  break;
   606  			}
   607  	}
   608  
   609  	// ディレクトリ部分
   610  	*r = (part==nam ? (const char*)"" : x->m_psArc->basedir);
   611  
   612  	// 名前部分
   613  	if( part != dir )
   614  	{
   615  		if( *opt=='\0' || *opt=='+' )
   616  		{
   617  			// (arc)       : anmをそのまま返す
   618  			*r += anm;
   619  			// (arc+XXX)   : anmXXXを返す
   620  			if( *opt=='+' )
   621  				*r += (opt+1);
   622  		}
   623  		else
   624  		{
   625  			const char* ext = kiPath::ext(anm);
   626  			const char* add = "";
   627  			if( opt[0]=='-' && opt[1]=='.' )
   628  			{
   629  				// (arc-.XXX) : 末尾が.XXXだったら削除。
   630  				//            : そうでなければ後ろに.decompressed
   631  				if( 0!=ki_strcmpi( ext, opt+2 ) )
   632  					ext = anm + ki_strlen(anm), add = ".decompressed";
   633  			}
   634  			else if( opt[1]!='\0' )
   635  			{
   636  				// (arc.XXX)  : 最後の拡張子を.XXXに取り替え
   637  				add = opt;
   638  				switch(mycnf().extnum())
   639  				{
   640  				case 0: ext = anm + ::lstrlen(anm);break; 
   641  				case 1: ext = kiPath::ext(anm);    break;
   642  				default:ext = kiPath::ext_all(anm);break;
   643  				}
   644  			}
   645  			else
   646  			{
   647  				// (arc.)     : 拡張子を全て取り除く
   648  				switch(mycnf().extnum())
   649  				{
   650  				case 0: ext = anm + ::lstrlen(anm);break; 
   651  				case 1: ext = kiPath::ext(anm);    break;
   652  				default:ext = kiPath::ext_all(anm);break;
   653  				}
   654  			}
   655  			if( *ext )
   656  				ext--;
   657  
   658  			char buf[MAX_PATH];
   659  			ki_memcpy( buf, anm, ext-anm );
   660  			buf[ ext-anm ] = '\0';
   661  			*r += buf;
   662  			*r += add;
   663  		}
   664  
   665  		// 必要ならくくる
   666  		if( part==full )
   667  			r->quote();
   668  	}
   669  }
   670  
   671  static void selfR(
   672  	const char* writedir, const char* fullpath, bool lfn, kiVar* r )
   673  {
   674  	kiFindFile       f;
   675  	WIN32_FIND_DATA fd;
   676  	f.begin( kiStr(fullpath) += "\\*" );
   677  
   678  	kiVar t, t2, t3;
   679  	while( f.next(&fd) )
   680  	{
   681  		t = writedir;
   682  		t+= '\\';
   683  		t+= (lfn ? fd.cFileName : fd.cAlternateFileName);
   684  		if( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
   685  		{
   686  			t2 = t;
   687  			t  = "";
   688  			t3 = fullpath;
   689  			t3+= '\\';
   690  			t3+= (lfn ? fd.cFileName : fd.cAlternateFileName);
   691  			selfR( t2, t3, lfn, &t );
   692  		}
   693  		else
   694  		{
   695  			if( lfn )
   696  				t.quote();
   697  		}
   698  		*r += t;
   699  		*r += ' ';
   700  	}
   701  }
   702  
   703  void CArcB2e::CB2eCore::list( const char* opt, const CharArray& a, const BoolArray& b,int c, kiVar* r )
   704  {
   705  	//---------------------------//
   706  	//-- (list[r|\*.*] [slfn]) --//
   707  	//---------------------------//
   708  
   709  	if( m_mode!=mEnc ) // 解凍の場合
   710  	{
   711  		*r = "";
   712  
   713  		for( unsigned int i=0; i!=x->m_psAInfo->len(); i++ )
   714  			if( (*x->m_psAInfo)[i].selected )
   715  			{
   716  				// - で始まるヤツ対策をするか?
   717  				t = (*x->m_psAInfo)[i].inf.szFileName;
   718  				t.quote();
   719  				*r += t;
   720  				*r += ' ';
   721  			}
   722  	}
   723  	else // 圧縮の場合
   724  	{
   725  		// デフォルトオプション設定
   726  		bool lfn=true;
   727  		enum{ full, nam } part=nam;
   728  		// 指定があれば上書
   729  		if( c>=2 )
   730  		{
   731  			getarg( a[1],b[1],&t );
   732  			for( const char* p=t; *p; p++ )
   733  				switch(*p)
   734  				{
   735  				case 's': lfn=false; break;
   736  				case 'l': lfn=true;  break;
   737  				case 'f': part=full; break;
   738  				case 'n': part=nam;  break;
   739  				}
   740  		}
   741  		// 自前で再帰リストアップを行うか否か
   742  		bool selfrecurse = (*opt=='r');
   743  
   744  		// ディレクトリ名の後ろに付け足すもの。
   745  		if( *opt=='\\' || *opt=='/' )
   746  			opt++;
   747  
   748  		// リストアップ
   749  		kiVar t2,t3;
   750  		*r = "";
   751  		for( unsigned int i=0; i!=x->m_psList->len(); i++ )
   752  		{
   753  			// ファイル名部分
   754  			t = ( part==full ? *x->m_psDir : (const char*)"");
   755  			t += lfn ? (*x->m_psList)[i].cFileName : (*x->m_psList)[i].cAlternateFileName;
   756  
   757  			if( selfrecurse && ((*x->m_psList)[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
   758  			{
   759  				// セルフ再帰
   760  				t2 = t;
   761  				t  = "";
   762  				t3 = *x->m_psDir;
   763  				t3+= lfn ? (*x->m_psList)[i].cFileName : (*x->m_psList)[i].cAlternateFileName;
   764  				selfR( t2, t3, lfn, &t );
   765  			}
   766  			else
   767  			{
   768  				// ノーマル処理
   769  				if( *opt && ((*x->m_psList)[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
   770  					t += '\\', t += opt;
   771  				if( lfn )
   772  					t.quote();
   773  			}
   774  			*r += t;
   775  			*r += ' ';
   776  		}
   777  	}
   778  
   779  	r->removeTrailWS();
   780  }
   781  
   782  void CArcB2e::CB2eCore::resp( bool needq, const char* opt, const CharArray& a, const BoolArray& b,int c, kiVar* r )
   783  {
   784  	//-----------------------------//
   785  	//-- (resp[@|-o] (list) ...) --//
   786  	//-----------------------------//
   787  
   788  	// レスポンスファイル名作成
   789  	kiPath rspfile;
   790  	myapp().get_tempdir(rspfile);
   791  	rspfile += "filelist";
   792  
   793  	// オプションと結合して返す
   794  	*r  = opt;
   795  	*r += rspfile;
   796  
   797  	// ファイルへ書き込み
   798  	kiFile fp;
   799  	if( !fp.open( rspfile,false ) )
   800  		return;
   801  
   802  	kiVar tmp;
   803  	for( int i=1; i<c; i++ )
   804  	{
   805  		// fpへ各引数をsplitしながら書き込む
   806  		getarg( a[i],b[i],&tmp );
   807  
   808  		for( const char *s,*p=tmp; *p; p++ )
   809  		{
   810  			// 余分な空白はスキップ
   811  			while( *p==' ' )
   812  				p++;
   813  			if( *p=='\0' )
   814  				break;
   815  
   816  			// 引数の終わりへ…
   817  			s=p;
   818  			for( int q=0; *p!='\0' && (*p!=' ' || (q&1)!=0); p++ )
   819  				if( *p=='"' )
   820  					q++;
   821  
   822  			// "のつじつま合わせ一号
   823  			if( !needq && *s=='"' )
   824  			{
   825  				s++;
   826  				if( p!=s && *(p-1)=='"' )
   827  					p--;
   828  			}
   829  
   830  			fp.write( s, p-s );
   831  			fp.write( "\r\n", 2 );
   832  
   833  			// "のつじつま合わせ二号
   834  			if( *p=='"' )
   835  				p++;
   836  			if( *p=='\0' )
   837  				break;
   838  		}
   839  	}
   840  }
   841  
   842  void CArcB2e::CB2eCore::input( const char* msg, const char* defval, kiVar* r )
   843  {
   844  	struct CB2eInputDlg : public kiDialog
   845  	{
   846  		const char* msg;
   847  		const char* def;
   848  		kiVar*      res;
   849  
   850  		CB2eInputDlg( const char* m, const char* d, kiVar* r )
   851  			: kiDialog( IDD_PASSWORD ), msg(m), def(d), res(r) {}
   852  		BOOL onInit()
   853  			{
   854  				sendMsgToItem( IDC_EDIT, WM_SETTEXT, 0, (LPARAM)def );
   855  				sendMsgToItem( IDC_MESSAGE, WM_SETTEXT, 0, (LPARAM)msg );
   856  				::ShowWindow( item(IDC_MASK), SW_HIDE );
   857  				::ShowWindow( item(IDCANCEL), SW_HIDE );
   858  				::EnableWindow( item(IDC_MASK), FALSE );
   859  				::EnableWindow( item(IDCANCEL), FALSE );
   860  				::SetFocus( item(IDC_EDIT) );
   861  				return TRUE;
   862  			}
   863  		bool onOK()
   864  			{
   865  				char* buf = new char[32768];
   866  				sendMsgToItem( IDC_EDIT, WM_GETTEXT, 32768, (LPARAM)buf );
   867  				*res = buf;
   868  				delete [] buf;
   869  				return true;
   870  			}
   871  	};
   872  
   873  	CB2eInputDlg d( msg, defval, r );
   874  	d.doModal( app()->mainhwnd() );
   875  }
   876