1 /*--------------------------------------------------------------------
2   filer 0.2.7
3 
4     Copyright (c) 1997,1998,1999,2000 SASAKI Shunsuke.
5     All rights reserved.
6 --------------------------------------------------------------------*/
7 #include	"sh.h"
8 #include	"filer.h"
9 
10 #if	TIME_WITH_SYS_TIME
11 #	include	<sys/time.h>
12 #	include	<time.h>
13 #else
14 #	if HAVE_SYS_TIME_H
15 #		include	<sys/time.h>
16 #	else
17 #		include	<time.h>
18 #	endif
19 #endif
20 
21 #if 0
22 typedef	struct	fitem
23 {
24 	char			*fn;
25 	char			*e;
26 	struct	stat	stat;
27 
28 	struct	fitem	*next;
29 }	fitem_t;
30 
31 typedef	struct
32 {
33 	fitem_t	*fitem;
34 	int 	n;
35 }	flist_t;
36 
37 typedef	struct
38 {
39 	char	path[LN_path +1];
40 
41 	menu_t	menu;
42 	bool	df;
43 
44 	flist_t	flist;
45 	fitem_t	**findex;
46 	int 	*mark;
47 	int 	markmax;
48 	int 	marknum;
49 
50 	char	match[LN_path+1];
51 }	fw_t;
52 fw_t	fw[2];
53 #define	fw_c	fw[eff.wa]
54 
55 typedef	struct
56 {
57 	int 	wn;			/* window�ο� */
58 	int 	wa;			/* Window Active ���� */
59 	bool	df;			/* dirty flag */
60 
61 	int 	sort[2];	/* sort���� */
62 }	eff_t;
63 eff_t	eff;
64 
65 enum	{SA_none,SA_fname,SA_ext};
66 
67 typedef struct	fop
68 {
69 	int 	(*file_func)(const char*,struct stat *,const char*, struct fop*);
70 	int 	(*dir_func)(const char*,struct stat *,const char*
71 														,bool, struct fop*);
72 	char    *title;
73 
74 	int 	om;		/* overwrite mode. */
75 	int 	pfm;	/* permition force mode. */
76 
77 	int 	en;		/* error number */
78 }	fop_t;
79 
80 #endif
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 /* �ǥ��쥯�ȥ��ư������� */
98 
99 typedef	struct
100 {
101 	int 	ct;
102 
103 	char	path[LN_path+1];
104 	char	name[LN_path+1];
105 }	dm_t;
106 
107 #define	MAX_dm	64
108 
109 dm_t	dm[MAX_dm];
110 int 	dm_num, dm_loc;
111 
dm_init()112 void	dm_init()
113 {
114 	int 	i;
115 
116 	dm_num=0;
117 	dm_loc=0;
118 
119 	for (i=0;i<MAX_dm;++i)
120 		dm[i].ct=0;
121 }
122 
dm_set(const char * p,const char * s)123 void	dm_set(const char *p,const char *s)
124 {
125 	int 	i,a,b;
126 	char	buf[LN_path+1];
127 	char	path[LN_path+1];
128 
129 	realpath(p, path);
130 	strcpy(buf, s);
131 	if (*buf!='\0'&& buf[strlen(buf)-1]=='/')
132 		buf[strlen(buf)-1]='\0';
133 
134 	for (i=0;i<dm_num;++i)
135 		{
136 		 if (strcmp(dm[i].path,path)==0)
137 		 	{
138 		 	 strcpy(dm[i].name,buf);
139 		 	 dm[i].ct=++dm_loc;
140 		 	 return ;
141 		 	}
142 		}
143 
144 	if (dm_num<MAX_dm)
145 		{
146 		 strcpy(dm[dm_num].path,path);
147 		 strcpy(dm[dm_num].name,buf);
148 		 dm[dm_num].ct=++dm_loc;
149 		 ++dm_num;
150 		 return;
151 		}
152 
153 	a=dm[0].ct;
154 	b=0;
155 	for (i=1;i<MAX_dm;++i)
156 		{
157 		 if (a>dm[i].ct)
158 		 	{
159 		 	 a=dm[i].ct;
160 		 	 b=i;
161 		 	}
162 		}
163 
164 	strcpy(dm[b].path,path);
165 	strcpy(dm[b].name,buf);
166 	dm[b].ct=++dm_loc;
167 }
168 
dm_get(const char * p,char * s)169 void	dm_get(const char *p,char *s)
170 {
171 	int 	i;
172 	char	path[LN_path+1];
173 
174 	realpath(p, path);
175 
176 	*s='\0';
177 	for(i=0;i<dm_num;++i)
178 		{
179 		 if (strcmp(dm[i].path,path)==0)
180 		 	{
181 		 	 strcpy(s,dm[i].name);
182 		 	 return;
183 		 	}
184 		}
185 	return;
186 }
187 
188 
189 
190 
fw_init(fw_t * fwp,const char * s,int a)191 void	fw_init(fw_t *fwp, const char *s,int a)
192 {
193 	char	path[LN_path+1];
194 
195 	*fwp->match='\0';
196 	if (s!=NULL)
197 		strcpy(fwp->path, s); else
198 		{
199 		 getcwd(path, LN_path);
200 		 sprintf(fwp->path, "%s/", path);
201 		}
202 
203 	fwp->flist.fitem=NULL;
204 	fwp->flist.n=0;
205 	fwp->findex=NULL;
206 
207 	menu_iteminit(&fwp->menu);
208 	fwp->menu.title= fwp->path;
209 
210 	fwp->menu.drp->sizex=(fwp->menu.drp->sizex+1)/2;
211 	if (a==1)
212 		fwp->menu.drp->x +=fwp->menu.drp->sizex;
213 }
214 
eff_init(const char * s1,const char * s2)215 void	eff_init(const char *s1, const char *s2)
216 {
217 	eff.wa=0;
218 	eff.wn=1;
219 	eff.sort[0]=SA_ext;
220 	eff.sort[1]=SA_fname;
221 
222 	fw_init(&fw[0],s1,0);
223 	fw_init(&fw[1],s2,1);
224 
225 	dm_init();
226 }
227 
228 
229 
fw_getstat(fw_t * fwp,int a)230 struct stat	*fw_getstat(fw_t *fwp,int a)
231 {
232 	if (a==-1)
233 		a=fwp->menu.cy+fwp->menu.sy;
234 //	min(a,fwp->flist.n);
235 
236 	return &fwp->findex[a]->stat;
237 }
238 
239 
fw_getfi(fw_t * fwp,int a)240 fitem_t	*fw_getfi(fw_t *fwp,int a)
241 {
242 	if (a==-1)
243 		a=fwp->menu.cy+fwp->menu.sy;
244 	return fwp->findex[a];
245 }
246 
fwc_chdir(const char * s,bool f)247 void	fwc_chdir(const char *s,bool f)
248 {
249 	char	path[LN_path+1];
250 	bool	uf;
251 
252 	if (*s=='\0')
253 		return;
254 
255 	if (strcmp(s,"..")==0)
256 		{
257 		 uf=TRUE;
258 		 sprintf(path,"%s..",fw_c.path);
259 		 reg_path(NULL, path,FALSE);
260 		}else
261 		{
262 		 uf=FALSE;
263 		 if (f)
264 		 	strcpy(path,s); else
265 		 	sprintf(path,"%s%s",fw_c.path,s);
266 		}
267 
268 	reg_path(fw_c.path, path,FALSE);
269 	if (dir_isdir(path))
270 		{
271 		 dm_set(fw_c.path, fw_c.findex[fw_c.menu.cy+fw_c.menu.sy]->fn);
272 		 if (uf&& strcmp(fw_c.path,"/")!=0)
273 		 	dm_set(path,fw_c.path+strlen(path));
274 
275 		 strcpy(fw_c.path,path);
276 
277 		 if (!uf|| strcmp(fw_c.path,"/")==0)
278 		 	dm_get(path,fw_c.match); else
279 		 	{
280 		 	 strcpy(fw_c.match,fw_c.path+ strlen(path));
281 		 	 if (*fw_c.match!='\0' &&fw_c.match[strlen(fw_c.match)-1]=='/')
282 		 	 	fw_c.match[strlen(fw_c.match)-1]='\0';
283 		 	}
284 
285 		 fw_c.df=TRUE;
286 		}
287 }
288 
fw_match(fw_t * fwp)289 void	fw_match(fw_t *fwp)
290 {
291 	int 	i;
292 
293 	i=fwp->flist.n-1;
294 
295 	while (i>0 && strcmp(fwp->match, fwp->findex[i]->fn)!=0)
296 		--i;
297 
298 	menu_csrmove(&fwp->menu, i);
299 }
300 
301 
302 
303 
304 
305 
fitem_free(fitem_t * fip)306 fitem_t	*fitem_free(fitem_t *fip)
307 {
308 	fitem_t	*next;
309 
310 	if (fip==NULL)
311 		return NULL;
312 	next=fip->next;
313 
314 	free(fip->fn);
315 	free(fip);
316 
317 	return next;
318 }
319 
fw_free(fw_t * fwp)320 void	fw_free(fw_t *fwp)
321 {
322 	fitem_t	*fitem;
323 
324 	menu_itemfin(&fwp->menu);
325 
326 	free(fwp->findex);
327 	fitem=fwp->flist.fitem;
328 	while(fitem!=NULL)
329 		fitem=fitem_free(fitem);
330 	fwp->flist.fitem=NULL;
331 	fwp->flist.n=0;
332 }
333 
fitem_mk(const char * path,char * s)334 fitem_t	*fitem_mk(const char *path, char *s)
335 {
336 	char	buf[LN_path+1], *p;
337 	fitem_t	*fitem;
338 
339 	fitem=(fitem_t *)mem_alloc(sizeof(fitem_t));
340 	fitem->next=NULL;
341 
342 	fitem->fn=s;
343 
344 	p=dir_pext(s);
345 	if (p==NULL)
346 		fitem->e=s+strlen(s); else
347 		fitem->e=p;
348 
349 	sprintf(buf,"%s/%s",path, s);
350 	if (strcmp(s,"..")==0)
351 		reg_path(NULL, buf, FALSE);
352 	stat(buf, &fitem->stat);
353 
354 	return fitem;
355 }
356 
357 
358 #if 1
359 
flist_set(flist_t * flp,const char * path)360 void	flist_set(flist_t *flp,const char *path)
361 {
362 	char	**p;
363 	fitem_t	*fitem;
364 
365 	p=dir_glob(path, TRUE);
366 
367 	fitem=  flp->fitem= fitem_mk(path, p[0]);
368 	flp->n= 1;
369 
370 	while(p[flp->n]!=NULL)
371 		{
372 		 fitem->next= fitem_mk(path, p[flp->n]);
373 		 fitem= fitem->next;
374 		 ++flp->n;
375 		}
376 	free(p);
377 }
378 
379 #else
380 
flist_set(flist_t * flp,const char * path)381 void	flist_set(flist_t *flp,const char *path)
382 {
383 	DIR 			*dirp;
384 	struct	dirent	*dp;
385 	fitem_t			*fitem,*next;
386 
387 	flp->fitem=NULL;
388 	flp->n=0;
389 
390 	dirp=opendir(path);
391 	if (dirp==NULL)
392 		{
393 		 flp->fitem=fitem_mk(path,"..");
394 		 ++flp->n;
395 		 return;
396 		}
397 
398 	for(;;)
399 		{
400 		 dp=readdir(dirp);
401 		 if (dp==NULL)
402 		 	break;
403 		 if (strcmp(dp->d_name, ".")==0)
404 		 	continue;
405 
406 		 next=fitem_mk(path, dp->d_name);
407 		 if (flp->fitem==NULL)
408 		 	flp->fitem=next; else
409 		 	fitem->next=next;
410 		 fitem=next;
411 		 ++flp->n;
412 		}
413 	closedir(dirp);
414 }
415 
416 #endif
417 
findex_comp(const void * x,const void * y)418 static	int 	findex_comp(const void *x,const void *y)
419 {
420 	fitem_t	*fi_x,*fi_y;
421 	int 	i,j;
422 
423 	fi_x=*(fitem_t **)x;
424 	fi_y=*(fitem_t **)y;
425 
426 	if (strncmp(fi_x->fn,"..",2)==0)
427 		return -1;
428 	if (strncmp(fi_y->fn,"..",2)==0)
429 		return 1;
430 
431 	if ((fi_x->stat.st_mode&S_IFMT)== S_IFDIR&& (fi_y->stat.st_mode&S_IFMT)!=S_IFDIR)
432 		return -1;
433 	if ((fi_x->stat.st_mode&S_IFMT)!= S_IFDIR&& (fi_y->stat.st_mode&S_IFMT)==S_IFDIR)
434 		return 1;
435 
436 	if (*fi_x->fn=='.'&& *fi_y->fn!='.')
437 		return -1;
438 	if (*fi_x->fn!='.'&& *fi_y->fn=='.')
439 		return 1;
440 
441 	for (i=0;i<2;++i)
442 		{
443 		 j=1;
444 		 switch(eff.sort[i])
445 		 	{
446 		  case SA_none:
447 		  	 return 0;
448 		  case SA_fname:
449 		  	 j=strcmp(fi_x->fn, fi_y->fn); //!! ��̩��Ƚ���
450 		  	 break;
451 		  case SA_ext:
452 		  	 j=strcmp(fi_x->e ,fi_y->e);
453 		  	 break;
454 		 	}
455 		 if (j!=0)
456 		 	return j;
457 		}
458 	return 0;
459 }
460 
461 
findex_get(flist_t * flp)462 fitem_t	**findex_get(flist_t *flp)
463 {
464 	fitem_t	**findex;
465 	fitem_t	*fitem;
466 	int 	i;
467 
468 	findex=(fitem_t **)mem_alloc(flp->n* sizeof(int *));
469 
470 	fitem=flp->fitem;
471 	for (i=0;i<flp->n;++i)
472 		{
473 		 findex[i]=fitem;
474 		 fitem=fitem->next;
475 		}
476 
477 	qsort(findex, i, sizeof(fitem_t **), findex_comp);
478 
479 	return findex;
480 }
481 
prt_kmsize(char * s,off_t n)482 void	prt_kmsize(char *s,off_t n)
483 {
484 	const	char	*scale=" KMGT";
485 
486 	if (n<(off_t)10*1000)
487 		{
488 		 sprintf(s," %4d", (int)n);
489 		 return;
490 		}
491 
492 	while(n>=(off_t)10*1000 && *scale!='\0')
493 		{
494 		 n/=1000;
495 		 ++scale;
496 		}
497 
498 	sprintf(s,"%4d%c", (int)n, *scale);
499 }
500 
fw_item_proc(int a,mitem_t * mip,void * vp)501 static	void	fw_item_proc(int a,mitem_t *mip,void *vp)
502 {
503 	char	buf[MAXLINESTR+1];
504 	char	*s,*p;
505 	fw_t	*fwp;
506 
507 	fwp=vp;
508 	s=mip->str;
509 
510 	strjfcpy(s, fwp->findex[a]->fn, MAXLINESTR, fwp->menu.drp->sizex-30);
511 	p=fwp->findex[a]->e;
512 	if (*p=='\0')
513 		strcat(s,"     "); else
514 		{
515 		 int 	m, n;
516 
517 		 n=strlen(s);
518 		 m=fwp->findex[a]->e - fwp->findex[a]->fn-1;
519 		 if (m<n)
520 		 	memset(s+m, ' ', n-m);
521 
522 		 strcat(s,".");
523 		 strjfcpy(s+strlen(s),p,MAXLINESTR,4); // !MAXLINESTR
524 		}
525 
526 	strcat(s," ");
527 	if ((fwp->findex[a]->stat.st_mode&S_IFMT)==S_IFDIR)
528 		{
529 		 strcat(s,"<DIR>");
530 		 mip->cc=sysinfo.c_eff_dirc;
531 		 mip->nc=sysinfo.c_eff_dirn;
532 		}else
533 		{
534 		 prt_kmsize(buf, fwp->findex[a]->stat.st_size);
535 		 strcat(s, buf);
536 
537 		 mip->cc=sysinfo.c_eff_normc;
538 		 mip->nc=sysinfo.c_eff_normn;
539 		}
540 
541 	strftime(buf,15,"%y/%m/%d %R", localtime(&fwp->findex[a]->stat.st_mtime));
542 	sprintf(s+strlen(s), " %s",buf);
543 }
544 
fw_make(fw_t * fwp)545 void	fw_make(fw_t *fwp)
546 {
547 	int 	sizex;
548 
549 	sizex=-1;
550 
551 	if (fwp->flist.fitem!=NULL)
552 		{
553 		 fw_free(fwp);
554 		 sizex=fwp->menu.drp->sizex;
555 		}
556 
557 	dm_get(fwp->path, fwp->match);
558 
559 	flist_set(&fwp->flist,fwp->path);
560 	fwp->findex=findex_get(&fwp->flist);
561 
562 	fwp->marknum=0;
563 	fwp->markmax=0;
564 	fwp->mark=mem_alloc(sizeof(int)*fwp->flist.n);
565 	memset(fwp->mark,0,sizeof(int)*fwp->flist.n);
566 
567 	fwp->menu.sy=0;
568 	fwp->menu.cy=0;
569 
570 	menu_itemmake(&fwp->menu,fw_item_proc,fwp->flist.n,fwp);
571 
572 	if (sizex!=-1)
573 		fwp->menu.drp->sizex=sizex;
574 
575 	fw_match(fwp);
576 }
577 
578 
fw_getmarkfirst(fw_t * fwp)579 int 	fw_getmarkfirst(fw_t *fwp)
580 {
581 	int 	n,m;
582 	int 	i;
583 
584 	m=-1;
585 	n=0;
586 	for (i=0;i<fwp->flist.n;++i)
587 		{
588 		 if (fwp->mark[i]!=0)
589 		 	{
590 		 	 if (n==0)
591 		 	 	{
592 		 	 	 n=fwp->mark[i];
593 		 	 	 m=i;
594 		 	 	} else
595 		 	 	{
596 		 	 	 if (n>fwp->mark[i])
597 		 	 	 	{
598 		 	 	 	 n=fwp->mark[i];
599 		 	 	 	 m=i;
600 		 	 	 	}
601 		 	 	}
602 		 	}
603 		}
604 	return m;
605 }
606 
fw_chmark(fw_t * fwp,int a)607 void	fw_chmark(fw_t *fwp,int a)
608 {
609 	int 	n;
610 
611 	n= a!=-1? a: fwp->menu.cy+fwp->menu.sy;
612 
613 	if (strcmp(fwp->findex[n]->fn,"..")==0)
614 		return;
615 
616 	if (fwp->mark[n]==0)
617 		{
618 		 fwp->mark[n]=++fwp->markmax;
619 		 ++fwp->marknum;
620 		} else
621 		{
622 		 fwp->mark[n]=0;
623 		 --fwp->marknum;
624 		 if (fwp->marknum==0)
625 		 	fwp->markmax=0;
626 		}
627 }
628 
fw_chmarkall(fw_t * fwp)629 void	fw_chmarkall(fw_t *fwp)
630 {
631 	int	i;
632 
633 	if (fwp->marknum==0)
634 		{
635 		 for (i=0;i<fwp->flist.n;++i)
636 		 	{
637 		 	 if ((fw_getstat(fwp, i)->st_mode &S_IFMT)!=S_IFDIR)
638 		 	 	fw_chmark(fwp, i);
639 		 	}
640 		} else
641 		{
642 		 while((i=fw_getmarkfirst(fwp))!=-1)
643 		 	fw_chmark(fwp, i);
644 		}
645 }
646 
647 /* file opration */
648 
select_readonly(fop_t * fop)649 static	bool	select_readonly(fop_t *fop)
650 {
651 	int 	res;
652 
653 	if (fop->pfm!=0)
654 		return fop->pfm==FP_force;
655 
656 	system_msg("�꡼�ɥ���꡼�Ǥ���");
657 
658 	res=menu_vselect(term_sizex()/2, term_sizey()/2
659 					, 4, "Y) ��������", "N) �������ʤ�"
660 					,"A) �ʹ����ƽ�������", "K) �ʹ����ƽ������ʤ�");
661 
662 
663 	RefreshMessage();
664 //	eff.df=TRUE;
665 
666 	switch (res)
667 		{
668 	 case 2:
669 	 	 fop->pfm=FP_force;
670 	 case 0:
671 	 	 return TRUE;
672 	 case 3:
673 	 	 fop->pfm=FP_ignore;
674 	 	}
675 	return FALSE;
676 }
677 
678 
fw_fop_file(const char * srcpath,const char * fn,struct stat * srcstp,const char * dstpath,fop_t * fop)679 int 	fw_fop_file(const char *srcpath,const char *fn,struct stat *srcstp
680 			,const char *dstpath,fop_t *fop)
681 {
682 	char	dstfn[LN_path+1],srcfn[LN_path+1];
683 	char	tmp[LN_path+1];
684 	struct	stat	dstst;
685 	int 	res;
686 
687 //fprintf(stderr,"fop_file ");
688 
689 	sprintf(srcfn,"%s%s",srcpath,fn);
690 	if (dstpath!=NULL)
691 		sprintf(dstfn,"%s%s",dstpath,fn);
692 
693 //fprintf(stderr,"%s -> %s\n",srcfn,dstfn);
694 
695 	for (;;)
696 		{
697 		 if (dstpath!=NULL)
698 		 	{
699 		 	 if (stat(dstfn,&dstst)==0 || errno!=ENOENT)
700 		 	 	{
701 //fprintf(stderr,"%s(%x) -> %s(%x)\n"
702 //	,srcfn, srcstp->st_ino, dstfn, dstst.st_ino);
703 
704 		 	 	 if (fop->om==0)
705 		 	 	 	{
706 					 fop->om=1+menu_vselect(term_sizex()/2, term_sizey()/2, 4
707 					 	, "O) ���ƾ��", "U) ���������դ�"
708 					 	, "N) Ʊ̾��ʣ�̤��ʤ�", "R) ̾�����Ѥ���");
709 
710 //		 	 	 	 eff.df=TRUE;
711 		 	 	 	}
712 
713 		 	 	 switch(fop->om)
714 		 	 	 	{
715 		 	 	  case 0:
716 		 	 	  	 return FR_end;
717 		 	 	  case FO_owrite:
718 		 	 	  	 break;
719 		 	 	  case FO_update:
720 		 	 	  	 if (dstst.st_mtime < srcstp->st_mtime)
721 		 	 	  	 	break;
722 		 	 	  	 return FR_ok;
723 		 	 	  case FO_rename:
724 		 	 	  	 fop->om=0;
725 		 	 	  	 strcpy(tmp,fn);
726 		 	 	  	 if (GetS("Rename :",tmp)==ESCAPE)
727 		 	 	  	 	return FALSE;
728 		 	 	  	 sprintf(dstfn,"%s%s",dstpath,tmp);
729 		 	 	  	 continue;
730 		 	 	  case FO_none:
731 		 	 	  	 return FR_ok;
732 		 	 	 	}
733 		 	 	 if (access(dstfn,W_OK)<0&& !select_readonly(fop))
734 		 	 	 	return FR_ok;
735 
736 		 	 	 unlink(dstfn);
737 		 	 	}
738 		 	}
739 
740 		 res=fop->file_func(srcfn, srcstp, dstfn, fop);
741 		 if (res!=FR_err)
742 		 	return res;
743 
744 		 res=menu_vselect(term_sizex()/2, term_sizey()/2, 3,
745 		 	"A) ���", "R) �ƻ�", "S) ��³");
746 
747 //		 eff.df=TRUE;
748 
749 		 switch(res)
750 		 	{
751 		  case -1:
752 		  case 0:
753 		  	 return FR_err;
754 		  case 1:
755 		  	 continue;
756 		  case 2:
757 		  	 return FR_ok;
758 		  	}
759 		}
760 }
761 
fw_fop_dir(const char * srcpath,const char * fn,struct stat * srcstp,const char * dstpath,fop_t * fop,bool wf)762 int 	fw_fop_dir(const char *srcpath,const char *fn,struct stat *srcstp
763 			,const char *dstpath, fop_t *fop, bool wf)
764 {
765 	char	dstfn[LN_path+1],srcfn[LN_path+1];
766 	struct	stat	dstst;
767 	int 	res;
768 	bool	f;
769 
770 	sprintf(srcfn,"%s%s",srcpath,fn);
771 	if (dstpath!=NULL)
772 		{
773 		 sprintf(dstfn,"%s%s",dstpath,fn);
774 		 if (stat(dstfn,&dstst)==0)
775 		 	{
776 		 	 if ((dstst.st_mode &S_IFMT)==S_IFDIR)
777 		 	 	{
778 		 	 	 chmod(dstfn,srcstp->st_mode);
779 		 	 	 touchfile(dstfn, srcstp->st_atime, srcstp->st_mtime);
780 
781 		 	 	 return FR_ok;
782 		 	 	}
783 
784 		 	 inkey_wait("�ǥ��쥯�ȥ��Ʊ̾�Υե����뤬¸�ߤ��ޤ���");
785 		 	 return FR_err;
786 		 	}
787 //	 	 if (errno!=ENOENT)
788 		}
789 
790 	f=TRUE;
791 	for (;;)
792 		{
793 		 res=fop->dir_func(srcfn, srcstp, dstfn, wf, fop);
794 		 if (res!=FR_err)
795 		 	return res;
796 		 res=menu_vselect(term_sizex()/2, term_sizey()/2, 3,
797 		 	"A) ���", "R) �ƻ�", "S) ��³");
798 
799 //		 eff.df=TRUE;
800 
801 		 switch(res)
802 		 	{
803 		  case -1:
804 		  case 0:
805 		  	 return FR_err;
806 		  case 1:
807 		  	 continue;
808 		  case 2:
809 		  	 return FR_ok;
810 		  	}
811 		}
812 }
813 
fw_fop_list(fitem_t ** findex,size_t fi_nums,const char * srcpath,const char * dstpath,fop_t * fop)814 int 	fw_fop_list(fitem_t **findex, size_t fi_nums
815 			,const char *srcpath, const char *dstpath
816 			,fop_t *fop)
817 {
818 	struct	stat	*srcstp;
819 	int 	res;
820 	char	*p;
821 	int 	i;
822 
823 	fitem_t	**fip;
824 	flist_t	fl;
825 	fitem_t	*fitem;
826 	char	srctmp[LN_path+1], dsttmp[LN_path+1];
827 
828 //fprintf(stderr,"*%d %s -> %s\n",fi_nums, srcpath,dstpath);
829 
830 	for (i=0;i<fi_nums;++i)
831 		{
832 		 srcstp=&findex[i]->stat;
833 //fprintf(stderr,"%03d:%s%s -> %s \n",i, srcpath,findex[i]->fn,dstpath);
834 
835 		 if ((srcstp->st_mode& S_IFMT)!=S_IFDIR)
836 			res=fw_fop_file(srcpath, findex[i]->fn, srcstp, dstpath, fop); else
837 			{
838 			 if (strcmp(findex[i]->fn,".")==0|| strcmp(findex[i]->fn,"..")==0)
839 			 	continue;
840 
841 
842 			 sprintf(srctmp,"%s%s/",srcpath,findex[i]->fn);
843 			 if (dstpath!=NULL)
844 			 	sprintf(dsttmp,"%s%s/",dstpath,findex[i]->fn);
845 			 system_msg(srctmp);
846 
847 			 res=fw_fop_dir(srcpath, findex[i]->fn, srcstp, dstpath, fop, TRUE);
848 			 if (res==FR_err)
849 			 	return FR_err;
850 			 if (res==FR_nonrec)
851 			 	continue;
852 
853 
854 		 	 flist_set(&fl,srctmp);
855 			 fip=findex_get(&fl);
856 //fprintf(stderr,"--- %s(%d) -> %s\n",srctmp, fl.n, dsttmp);
857 
858 		 	 fw_fop_list(fip, fl.n, srctmp, dstpath==NULL?NULL:dsttmp
859 		 	 	, fop);
860 
861 		 	 free(fip);
862 		 	 fitem=fl.fitem;
863 		 	 while(fitem!=NULL)
864 		 	 	fitem=fitem_free(fitem);
865 
866 
867 			 res=fw_fop_dir(srcpath, findex[i]->fn, srcstp, dstpath, fop, FALSE);
868 		 	}
869 		 if (res==FR_err|| res==FR_end)
870 		 	return res;
871 		}
872 	return FR_ok;
873 }
874 
875 
fw_fop(fw_t * srcfwp,const char * dstpath,char * title,int file_func (const char *,struct stat *,const char *,fop_t *),int dir_func (const char *,struct stat *,const char *,bool,fop_t *))876 void	fw_fop(fw_t *srcfwp, const char *dstpath
877 			,char *title
878 			,int file_func(const char*,struct stat*,const char*,fop_t*)
879 			,int dir_func(const char*,struct stat*,const char*,bool,fop_t*))
880 {
881 	int 	mn;
882 	int 	n;
883 	int 	res;
884 	fop_t	fo;
885 
886 	fo.title=title;
887 	fo.file_func=file_func;
888 	fo.dir_func=dir_func;
889 	fo.om=0;
890 	fo.pfm=0;
891 
892 	mn=fw_c.menu.cy +fw_c.menu.sy;
893 	for (;;)
894 		{
895 		 fitem_t	*fip;
896 
897 		 if (srcfwp->marknum==0)
898 		 	n=-1; else
899 		 	n=fw_getmarkfirst(srcfwp);
900 
901 		 if (n!=-1)
902 		 	{
903 		 	 menu_csrmove(&fw_c.menu, n);
904 //		 	 dsp_regview
905 //			 dsp_allview();
906 		 	}
907 
908 		 fip=fw_getfi(srcfwp,n);
909 
910 		 res=fw_fop_list(&fip, 1, srcfwp->path, dstpath, &fo);
911 		 if (n!=-1)
912 		 	fw_chmark(srcfwp,n);
913 
914 		 if (res==FR_err||res==FR_end)
915 		 	break;
916 		 if (srcfwp->marknum==0)
917 		 	break;
918 		}
919 	if (n!=-1)
920 		menu_csrmove(&fw_c.menu, mn);
921 }
922 
923 
cp_proc_dir(const char * src,struct stat * srcstp,const char * dst,bool wf,fop_t * fop)924 static	int		cp_proc_dir(const char *src,struct stat *srcstp,const char *dst
925 			,bool wf,fop_t *fop)
926 {
927 	if (!wf)
928 		return FR_ok;
929 
930 	if (mkdir(dst,0777)!=0)
931 		return FR_err;
932 
933 	chmod(dst,srcstp->st_mode);
934 	touchfile(dst, srcstp->st_atime, srcstp->st_mtime);
935 
936 	return FR_ok;
937 }
938 
939 #define	MAX_cpbuf	4096
940 
cp_proc_file(const char * src,struct stat * srcstp,const char * dst,fop_t * fop)941 static	int		cp_proc_file(const char *src,struct stat *srcstp
942 								,const char *dst,fop_t *fop)
943 {
944 	FILE	*fpr,*fpw;
945 	bool	ef;
946 
947 //fprintf(stderr,"cp*[%s]->[%s]\n",src,dst);
948 
949 	fpr=fopen(src,"r");
950 	if (fpr==NULL)
951 		return FR_err;
952 
953 	fpw=fopen(dst,"w");
954 	if (fpw==NULL)
955 		{
956 		 fclose(fpr);
957 		 return FR_err;
958 		}
959 
960 	ef=FALSE;
961 	for (;;)
962 		{
963 		 char	buf[MAX_cpbuf];
964 		 int 	n,m;
965 
966 		 n=fread(buf,1,MAX_cpbuf,fpr);
967 		 if (n==0)
968 		 	break;
969 		 m=0;
970 		 while(n-m>0)
971 		 	m=fwrite(buf+m,1,n-m,fpw);
972 		 if (m==0)
973 		 	{
974 		 	 ef=TRUE;
975 		 	 break;
976 		 	}
977 		}
978 
979 	fclose(fpr);
980 	fclose(fpw);
981 
982 	if (ef || ferror(fpr))
983 		{
984 		 unlink(dst);
985 		 return FR_err;
986 		}
987 
988 	chmod(dst,srcstp->st_mode);
989 	touchfile(dst, srcstp->st_atime, srcstp->st_mtime);
990 
991 	return FR_ok;
992 }
993 
mv_proc_dir(const char * src,struct stat * srcstp,const char * dst,bool wf,fop_t * fop)994 static	int		mv_proc_dir(const char *src,struct stat *srcstp,const char *dst
995 			,bool wf,fop_t* fop)
996 {
997 	if (!wf)
998 		{
999 		 rmdir(src);
1000 		 return FR_ok;
1001 		}
1002 
1003 	if (rename(src,dst)==0)
1004 		{
1005 		 touchfile(dst, srcstp->st_atime, srcstp->st_mtime);
1006 		 return FR_nonrec;
1007 		}
1008 
1009 	return cp_proc_dir(src,srcstp,dst,wf,fop);
1010 }
1011 
mv_proc_file(const char * src,struct stat * srcstp,const char * dst,fop_t * fop)1012 static	int 	mv_proc_file(const char *src,struct stat *srcstp
1013 								,const char *dst,fop_t *fop)
1014 {
1015 	int 	res;
1016 
1017 	if (rename(src,dst)==0)
1018 		return FR_ok;
1019 	res=cp_proc_file(src,srcstp,dst,fop);
1020 	if (res==FR_ok)
1021 		unlink(src);
1022 	return res;
1023 }
1024 
rm_proc_file(const char * src,struct stat * srcstp,const char * dst,fop_t * fop)1025 static	int 	rm_proc_file(const char *src,struct stat *srcstp
1026 									,const char *dst,fop_t *fop)
1027 {
1028 	if (access(src,W_OK)<0&& !select_readonly(fop))
1029 		return FR_ok;
1030 
1031 	if (unlink(src)==0)
1032 		return FR_ok;
1033 	return FR_err;
1034 }
1035 
rm_proc_dir(const char * src,struct stat * srcstp,const char * dst,bool wf,fop_t * fop)1036 static	int 	rm_proc_dir(const char *src,struct stat *srcstp,const char *dst
1037 			,bool wf,fop_t* fop)
1038 {
1039 	if (wf)
1040 		return FR_ok;
1041 
1042 	if (rmdir(src)==0)
1043 		return FR_ok;
1044 	return FR_err;
1045 }
1046 
fw_cpdest(char * s,fw_t * srcfwp,fw_t * dstfwp)1047 bool	fw_cpdest(char *s, fw_t *srcfwp, fw_t *dstfwp)
1048 {
1049 	char	srcpath[LN_path+1];
1050 
1051 	strcpy(srcpath,srcfwp->path);
1052 	reg_path(NULL, srcpath,TRUE);	// ??
1053 
1054 	if (dstfwp!=NULL)
1055 		{
1056 		 strcpy(s,dstfwp->path);
1057 		 reg_path(NULL, s,TRUE);
1058 //fprintf(stderr,"dst [%s]\n",s);
1059 		 if (strcmp(srcpath,s)!=0)	// !!��ʬ�β����ɤ��������å���Ԥ�
1060 		 	return TRUE;
1061 		}
1062 
1063 	*s='\0';
1064 	if (GetS("ʣ���� :",s)==ESCAPE)
1065 		return FALSE;
1066 //fprintf(stderr,"dst*[%s]\n",s);
1067 	reg_path(srcpath, s,FALSE);
1068 
1069 	if (strcmp(srcpath,s)==0)	// !!��ʬ�β����ɤ��������å���Ԥ�
1070 		return FALSE;
1071 //fprintf(stderr,"dst*[%s]\n",s);
1072 	return mole_dir(s);
1073 
1074 }
1075 
fw_copy(fw_t * srcfwp,fw_t * dstfwp)1076 void	fw_copy(fw_t *srcfwp,fw_t *dstfwp)
1077 {
1078 	char	buf[LN_path+1];
1079 
1080 	if (!fw_cpdest(buf,srcfwp,dstfwp))
1081 		return;
1082 
1083 	fw_fop(srcfwp, buf, "ʣ��", cp_proc_file, cp_proc_dir);
1084 	if (dstfwp!=NULL)
1085 		fw_make(dstfwp);
1086 }
1087 
fw_move(fw_t * srcfwp,fw_t * dstfwp)1088 void	fw_move(fw_t *srcfwp,fw_t *dstfwp)
1089 {
1090 	char	buf[LN_path+1];
1091 
1092 	if (!fw_cpdest(buf,srcfwp,dstfwp))
1093 		return;
1094 
1095 	fw_fop(srcfwp, buf, "��ư", mv_proc_file, mv_proc_dir);
1096 	fw_make(srcfwp);
1097 
1098 	if (dstfwp!=NULL)
1099 		fw_make(dstfwp);
1100 }
1101 
fw_remove(fw_t * srcfwp,fw_t * dstfwp)1102 void	fw_remove(fw_t *srcfwp,fw_t *dstfwp)
1103 {
1104 	if (keysel_ynq("������ޤ���������Ǥ��礦����")!=TRUE)
1105 		return;
1106 
1107 	fw_fop(srcfwp, NULL,"���", rm_proc_file, rm_proc_dir);
1108 	fw_make(srcfwp);
1109 }
1110 
fw_rename(fw_t * fwp)1111 void	fw_rename(fw_t *fwp)
1112 {
1113 	char	buf[LN_path+1], tmp[LN_path+1];
1114 	char	*fn;
1115 
1116 	fn=fw_c.findex[fw_c.menu.cy+fw_c.menu.sy]->fn;
1117 	strcpy(tmp, fn);
1118 	if (GetS("Rename :",tmp)==ESCAPE)
1119 		return;
1120 
1121 	getcwd(buf, LN_path);
1122 	chdir(fwp->path);
1123 	if (rename(fn, tmp)==0)
1124 		dm_set(fwp->path,tmp);
1125 	chdir(buf);
1126 
1127 }
1128 
fw_mkdir(fw_t * fwp)1129 void	fw_mkdir(fw_t *fwp)
1130 {
1131 	char	buf[LN_path+1],tmp[LN_path+1];
1132 
1133 	*tmp='\0';
1134 	if (GetS("Mkdir :",tmp)==ESCAPE)
1135 		return;
1136 	sprintf(buf,"%s%s",fwp->path,tmp);
1137 	mkdir(buf,0777);
1138 }
1139 
pval_parse(const char * s,char * t)1140 char	*pval_parse(const char *s, char *t)
1141 {
1142 	char	c;
1143 	char	*p, com[MAXLINESTR+1];
1144 
1145 //fprintf(stderr,"\npval [%s]\n", s);
1146 
1147 	c=' ';
1148 	p=com;
1149 	while (*s!='\0'&& *s!=c)
1150 		{
1151 		 if (*s=='(')
1152 		 	{
1153 		 	 c=')';
1154 		 	 ++s;
1155 		 	 continue;
1156 		 	}
1157 		 if (*s=='{')
1158 		 	{
1159 		 	 c='}';
1160 		 	 ++s;
1161 		 	 continue;
1162 			}
1163 		 *p++=*s++;
1164 		}
1165 	*p='\0';
1166 	if (*s!='\0')
1167 		++s;
1168 
1169 	*t='\0';
1170 //fprintf(stderr,"[%s]\n", com);
1171 	switch(*com)
1172 		{
1173 //	 case 'm':
1174 //		 if (fw_c.marknum>0)
1175 	 case 'f':
1176 		 strcpy(t, fw_c.findex[fw_c.menu.cy+fw_c.menu.sy]->fn);
1177 	 	 break;
1178 		}
1179 
1180 	return (char *)s;
1181 }
1182 
1183 
eff_exec()1184 bool	eff_exec()
1185 {
1186 	char	buf[LN_path+1],*q;
1187 	const	char	*p;
1188 	bool	f_input,f_dread;
1189 
1190 
1191 	*buf='\0';
1192 	f_input=FALSE;
1193 	f_dread=FALSE;
1194 	if (keyf_numarg()>0)
1195 		{
1196 		 p=keyf_getarg(0);
1197 		 q=buf;
1198 
1199 //fprintf(stderr,"[%s]\n", p);
1200 
1201 		 if (*p=='-')
1202 		 	{
1203 		 	 ++p;
1204 		 	 while (*p!='\0'&&!isspace(*p))
1205 		 	 	{
1206 		 	 	 switch (tolower(*p))
1207 		 	 	 	{
1208 		 	 	  case 'i':
1209 		 	 	  	 f_input=TRUE;
1210 		 	 	  	 break;
1211 		 	 	  case 'd':
1212 		 	 	  	 f_dread=TRUE;
1213 		 	 	  	 break;
1214 		 	 	  	}
1215 		 	 	 ++p;
1216 		 	 	}
1217 
1218 		 	 p=keyf_getarg(1);
1219 		 	 if (p==NULL)
1220 		 	 	p="";
1221 		 	}
1222 
1223 //fprintf(stderr,"[%s]\n", p);
1224 		 while(*p!='\0')
1225 		 	{
1226 //fprintf(stderr,"<%c>", *p);
1227 		 	 if (*p!='%')
1228 		 	 	*q++=*p++; else
1229 		 	 	{
1230 		 	 	 p=pval_parse(p+1,q);
1231 		 	 	 q+=strlen(q);
1232 		 	 	}
1233 		 	}
1234 		}
1235 
1236 	if (!f_input|| HisGets(buf, GETS_SHELL_MSG, SHELLS_SYSTEM) != NULL)
1237 		CommandCom(buf);
1238 
1239 	return f_dread;
1240 }
1241 
1242 
1243 
eff_filer(char * fn)1244 bool	eff_filer(char *fn)
1245 {
1246 	int 	c;
1247 	char	buf[LN_path+1], *p;
1248 	bool	f;
1249 
1250 //	term_cls();
1251 
1252 	fw_make(&fw[0]);
1253 	fw_make(&fw[1]);
1254 
1255 	*fn='\0';
1256 
1257 	if (eff.wn==1)
1258 		dsp_regrm(fw[1].menu.drp);
1259 
1260 	for (;;)
1261 		{
1262 		 dsp_allview();
1263 
1264 		 term_csrh();
1265 		 c=get_keyf(2);
1266 		 switch(c)
1267 		 	{
1268 		  case -1:
1269 		  	 continue;
1270 		  case KF_EffCursorUp:
1271 		  	 menu_csrmove(&fw_c.menu,fw_c.menu.cy +fw_c.menu.sy -1);
1272 		  	 continue;
1273 
1274 		  case KF_EffMarkChangeAll:
1275 		  	 fw_chmarkall(&fw[eff.wa]);
1276 		  	 continue;
1277 		  case KF_EffMarkChange:
1278 		  	 fw_chmark(&fw[eff.wa],-1);
1279 
1280 		  case KF_EffCursorDown:
1281 		  	 menu_csrmove(&fw_c.menu,fw_c.menu.cy +fw_c.menu.sy +1);
1282 		  	 continue;
1283 		  case KF_EffPageUp:
1284 		  	 menu_csrmove(&fw_c.menu,fw_c.menu.cy +fw_c.menu.sy -(fw_c.menu.drp->sizey-1));
1285 		  	 continue;
1286 		  case KF_EffPageDown:
1287 		  	 menu_csrmove(&fw_c.menu,fw_c.menu.cy +fw_c.menu.sy +(fw_c.menu.drp->sizey-1));
1288 		  	 continue;
1289 		  case KF_EffRollUp:
1290 		  	 menu_csrmove(&fw_c.menu,fw_c.menu.cy +fw_c.menu.sy -fw_c.menu.drp->sizey/4);
1291 		  	 continue;
1292 		  case KF_EffRollDown:
1293 		  	 menu_csrmove(&fw_c.menu,fw_c.menu.cy +fw_c.menu.sy +fw_c.menu.drp->sizey/4);
1294 		  	 continue;
1295 		  default:
1296 		  	 if (c&KF_normalcode)
1297 		  	 	{
1298 		  	 	 c&= ~KF_normalcode;
1299 		  	 	 if (isupper(c))
1300 		  	 	 	menu_csrnext(&fw_c.menu, c);
1301 		  	 	}
1302 		  	 continue;
1303 
1304 		  case KF_EffExec:
1305 		  	 if (!eff_exec())
1306 		  	 	continue;
1307 
1308 		  case KF_EffReRead:
1309 		  	 dm_set(fw_c.path, fw_c.findex[fw_c.menu.cy+fw_c.menu.sy]->fn);
1310 
1311 		  	 fw_make(&fw[eff.wa]);
1312 		  	 term_cls();
1313 		  	 continue;
1314 
1315 		  case KF_EffRename:
1316 		  	 fw_rename(&fw[eff.wa]);
1317 		  	 fw_make(&fw[eff.wa]);
1318 		  	 continue;
1319 		  case KF_EffMkdir:
1320 		  	 fw_mkdir(&fw[eff.wa]);
1321 		  	 fw_make(&fw[eff.wa]);
1322 		  	 continue;
1323 
1324 		  case KF_EffWindowChange:
1325 		  	 if (eff.wn==2)
1326 		  	 	{
1327 		  	 	 fw_c.menu.df=TRUE;
1328 		  	 	 eff.wa= (eff.wa==0)?1:0;
1329 		  	 	 fw_c.menu.df=FALSE;
1330 		  	 	}
1331 		  	 continue;
1332 		  case KF_EffWindowNumChange:
1333 		  	 if (eff.wn==1)
1334 		  	 	{
1335 		  	 	 eff.wn=2;
1336 		  	 	 fw[1].menu.df=TRUE;
1337 		  	 	 dsp_regadd(fw[1].menu.drp);
1338 		  	 	}else
1339 		  	 	{
1340 		 		 eff.wa=0;
1341 		  	 	 fw_c.menu.df=FALSE;
1342 		  	 	 eff.wn=1;
1343 		  	 	 dsp_regrm(fw[1].menu.drp);
1344 
1345 				 term_cls();
1346 		  	 	}
1347 		  	 continue;
1348 
1349 		  case KF_EffFileCp:
1350 		  	 fw_copy(&fw[eff.wa], eff.wn==2? &fw[eff.wa==0?1:0]: NULL);
1351 		  	 continue;
1352 		  case KF_EffFileMv:
1353 		  	 fw_move(&fw[eff.wa], eff.wn==2? &fw[eff.wa==0?1:0]: NULL);
1354 		  	 continue;
1355 		  case KF_EffFileRm:
1356 		  	 fw_remove(&fw[eff.wa],NULL);
1357 		  	 continue;
1358 
1359 		  case KF_EffChangeDir:
1360 		  	 if (keyf_numarg()>0)
1361 		  	 	{
1362 		  	 	 fwc_chdir(keyf_getarg(0), TRUE);
1363 		  	 	 fw_make(&fw[eff.wa]);
1364 //				 term_cls();
1365 		  	 	 continue;
1366 		  	 	}
1367 		  	 *buf='\0';
1368 		  	 if (GetS("Change Dir: ",buf))
1369 		  	 	{
1370 		  	 	 fwc_chdir(buf,TRUE);
1371 		  	 	 fw_make(&fw[eff.wa]);
1372 //				 term_cls();
1373 		  	 	}
1374 		  	 continue;
1375 
1376 		  case KF_EffReturn:
1377 		 	 p=fw_c.findex[fw_c.menu.cy+fw_c.menu.sy]->fn;
1378 
1379 		  	 if ((fw_c.findex[fw_c.menu.cy+fw_c.menu.sy]->stat.st_mode &S_IFMT)
1380 		  	 		==S_IFDIR)
1381 		  	 	{
1382 		  	 	 fwc_chdir(p, FALSE);
1383 		  	 	 fw_make(&fw[eff.wa]);
1384 //				 term_cls();
1385 		  	 	 continue;
1386 		  	 	}
1387 		  	 dm_set(fw_c.path, p);
1388 		  	 sprintf(fn,"%s%s",fw_c.path, p);
1389 		  	 f=TRUE;
1390 		  	 break;
1391 		  case KF_EffEscape:
1392 		  	 dm_set(fw_c.path, fw_c.findex[fw_c.menu.cy+fw_c.menu.sy]->fn);
1393 		  	 f=FALSE;
1394 		  	 break;
1395 		  	}
1396 
1397 		 break;
1398 		}
1399 
1400 	fw_free(&fw[0]);
1401 	fw_free(&fw[1]);
1402 
1403 	dsp_regrm(fw[0].menu.drp);
1404 	dsp_regrm(fw[1].menu.drp);
1405 //	dsp_regfin(fw[0].menu.drp);
1406 //	dsp_regfin(fw[1].menu.drp);
1407 
1408 
1409 	return f;
1410 }
1411 
1412 
1413 /*
1414 	2000/03/11 by Mia	add
1415 		returns if filer should be used.
1416 		this function is not static because this would be useful for others.
1417 */
need_filer(const char * pszFilename)1418 bool	need_filer( const char* pszFilename )
1419 {
1420 	if (*pszFilename=='\0')
1421 		return TRUE;
1422 
1423 	/*	if filename contains '*' or '?', yes.
1424 		Although shell expand this characters,
1425 		ESC-o doesn't.
1426 	*/
1427 	if (strchr(pszFilename, '*') != NULL ||
1428 		strchr(pszFilename, '?') != NULL)
1429 		return TRUE ;
1430 
1431 	/*	if it is a directory, yes. */
1432 	return dir_isdir(pszFilename);
1433 }
1434 
1435