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