1 /* $Id: dired.c,v 1.8 2001/02/18 19:29:29 amura Exp $ */
2 /* dired module for mg 2a	*/
3 /* by Robert A. Larson		*/
4 
5 /*
6  * $Log: dired.c,v $
7  * Revision 1.8  2001/02/18 19:29:29  amura
8  * split dir.c to port depend/independ
9  *
10  * Revision 1.7  2001/02/18 17:07:24  amura
11  * append AUTOSAVE feature (but NOW not work)
12  *
13  * Revision 1.6  2000/12/27 16:56:01  amura
14  * change d_makename() params for conservative reason, and bugfix in dires_()
15  *
16  * Revision 1.5  2000/12/14 18:06:24  amura
17  * filename length become flexible
18  *
19  * Revision 1.4  2000/09/21 17:28:29  amura
20  * replace macro _WIN32 to WIN32 for Cygwin
21  *
22  * Revision 1.3  2000/07/22 17:54:09  amura
23  * fix typo bug
24  *
25  * Revision 1.2  2000/06/27 01:49:42  amura
26  * import to CVS
27  *
28  * Revision 1.1  1999/05/21  02:45:06  amura
29  * Initial revision
30  *
31  */
32 
33 #include "config.h"	/* 90.12.20  by S.Yoshida */
34 #include "def.h"
35 
36 #ifndef NO_DIRED
37 
38 BUFFER *dired_();
39 #ifndef strncpy
40 extern char* strncpy();
41 #endif
42 
43 #ifdef	CHGMISC		/* 99.8.11 by M.Suzuki	*/
SearchDir(dirname)44 static int SearchDir(dirname)
45 char* dirname;
46 {
47     LINE *llp;
48 
49     for (llp=curbp->b_linep; lforw(llp)!=curbp->b_linep; llp=lforw(llp)){
50 #ifndef	max
51 #define	max(a,b)	(((a)<(b))?(b):(a))
52 #endif
53 	if (strncmp(dirname, llp->l_text, max(strlen(dirname),llength(llp)))
54 	   == 0 ){
55 	    curwp->w_dotp = llp;
56 	    curwp->w_flag |= WFEDIT | WFMOVE;
57 	    curwp->w_doto = llength(llp);
58 	    return TRUE;
59 	}
60     }
61     return FALSE;
62 }
63 #endif	/* CHGMISC	*/
64 
65 /*ARGSUSED*/
dired(f,n)66 dired(f, n)
67 int f, n;
68 {
69     char dirname[NFILEN];
70     BUFFER *bp;
71 #ifdef	CHGMISC		/* 1999.8.17 by M.Suzuki	*/
72     char *fname;
73 #endif	/* CHGMISC	*/
74 #ifdef	EXTD_DIR
75     int i;
76 
77     ensurecwd();
78     edefset(curbp->b_cwd);
79 #endif
80 
81     dirname[0] = '\0';
82 #ifndef NO_FILECOMP	/* 90.04.04  by K.Maeda */
83     if(eread("Dired: ", dirname, NFILEN, EFNEW | EFCR | EFFILE) == ABORT)
84 #else	/* NO_FILECOMP */
85     if(eread("Dired: ", dirname, NFILEN, EFNEW | EFCR) == ABORT)
86 #endif	/* NO_FILECOMP */
87 	return ABORT;
88 #ifdef	CHGMISC		/* 1999.8.17 by M.Suzuki	*/
89     if((fname = adjustname(dirname)) == NULL) {
90 	ewprintf("Bad directory name");
91 	return FALSE;
92     }
93     if( !ffisdir(fname) ){
94 	return filevisit_(fname,f,n);
95     }
96     if((bp = dired_(fname)) == NULL) return FALSE;
97 #else
98     if((bp = dired_(dirname)) == NULL) return FALSE;
99 #endif	/* CHGMISC	*/
100     curbp = bp;
101 #ifdef	EXTD_DIR
102     i = strlen(dirname);
103     if (curbp->b_cwd != NULL)
104 	free(curbp->b_cwd);
105     if ((curbp->b_cwd=malloc(i+2)) == NULL)
106 	return FALSE;
107     strcpy(curbp->b_cwd, dirname);
108     if (i >= 1) {
109 	if (curbp->b_cwd[i-1] != BDC1
110 #ifdef BDC2
111 	    && curbp->b_cwd[i-1] != BDC2
112 #endif
113 	    ) {
114 	    curbp->b_cwd[i] = BDC1;
115 	    curbp->b_cwd[i+1] = '\0';
116 	}
117     }
118 #endif	/* EXTD_DIR */
119 #ifdef	READONLY	/* 91.01.15  by K.Maeda */
120     curbp->b_flag |= BFRONLY;
121 #endif	/* READONLY */
122 #ifdef FEPCTRL
123     /* The following fepmode_off() is only effective if the provided
124        fepcontrol supports a doubled fepmode_off() feature.  That is,
125        the second call for the fepmode_off() is expected to change the
126        previous fep mode as off, without doing any actual fep control
127        since the fep mode has been already turned off by the first
128        call of the function.  So, the succeeding fepmode_on() will not
129        turn on the fep mode even if the previous fep mode was on
130        before the first call of fepmode_off().
131 
132        If this feature is not provided, entering dired does not affect
133        the fep mode.
134 
135        By Tillanosoft, Mar 21, 1999 */
136     fepmode_off();
137 #endif
138     return showbuffer(bp, curwp, WFHARD | WFMODE);
139 }
140 
141 /*ARGSUSED*/
d_otherwindow(f,n)142 d_otherwindow(f, n)
143 int f, n;
144 {
145     char dirname[NFILEN];
146     BUFFER *bp;
147     WINDOW *wp;
148 
149 #ifdef	EXTD_DIR
150     ensurecwd();
151     edefset(curbp->b_cwd);
152 #endif
153 
154     dirname[0] = '\0';
155 #ifndef NO_FILECOMP	/* 90.04.04  by K.Maeda */
156     if(eread("Dired other window: ", dirname, NFILEN, EFNEW | EFCR | EFFILE) == ABORT)
157 #else	/* NO_FILECOMP */
158     if(eread("Dired other window: ", dirname, NFILEN, EFNEW | EFCR) == ABORT)
159 #endif	/* NO_FILECOMP */
160 	return ABORT;
161 #ifdef	CHGMISC		/* 99.6.18 by M.Suzuki	*/
162     if((bp = dired_(dirname)) == NULL) return FALSE;
163 #else
164     if((bp = dired_(dirname)) == NULL) return FALSE;
165 #endif	/* CHGMISC	*/
166 #ifdef	READONLY	/* 91.01.15  by K.Maeda */
167     bp->b_flag |= BFRONLY;
168 #endif	/* READONLY */
169     if((wp = popbuf(bp)) == NULL) return FALSE;
170     curbp = bp;
171     curwp = wp;
172     return TRUE;
173 }
174 
175 /*ARGSUSED*/
d_del(f,n)176 d_del(f, n)
177 int f, n;
178 {
179     if(n < 0) return FALSE;
180     while(n--) {
181 	if(llength(curwp->w_dotp) > 0)
182 #ifdef	CHGMISC		/* 99.6.18 by M.Suzuki	*/
183 	    if(lgetc(curwp->w_dotp,0) != '/' &&
184 	       strncmp(curwp->w_dotp->l_text, "  total", 7) )
185 #endif	/* CHGMISC	*/
186 	    lputc(curwp->w_dotp, 0, 'D');
187 	if(lforw(curwp->w_dotp) != curbp->b_linep)
188 	    curwp->w_dotp = lforw(curwp->w_dotp);
189     }
190     curwp->w_flag |= WFEDIT | WFMOVE;
191     curwp->w_doto = 0;
192     return TRUE;
193 }
194 
195 /*ARGSUSED*/
d_undel(f,n)196 d_undel(f, n)
197 int f, n;
198 {
199     if(n < 0) return d_undelbak(f, -n);
200     while(n--) {
201 	if(llength(curwp->w_dotp) > 0)
202 #ifdef	CHGMISC		/* 99.6.18 by M.Suzuki	*/
203 	    if( lgetc(curwp->w_dotp,0) != '/' &&
204 		strncmp(curwp->w_dotp->l_text,"  total",7) )
205 #endif	/* CHGMISC	*/
206 	    lputc(curwp->w_dotp, 0, ' ');
207 	if(lforw(curwp->w_dotp) != curbp->b_linep)
208 	    curwp->w_dotp = lforw(curwp->w_dotp);
209     }
210     curwp->w_flag |= WFEDIT | WFMOVE;
211     curwp->w_doto = 0;
212     return TRUE;
213 }
214 
215 /*ARGSUSED*/
d_undelbak(f,n)216 d_undelbak(f, n)
217 int f, n;
218 {
219     if(n < 0) return d_undel(f, -n);
220     while(n--) {
221 	if(llength(curwp->w_dotp) > 0)
222 	    lputc(curwp->w_dotp, 0, ' ');
223 	if(lback(curwp->w_dotp) != curbp->b_linep)
224 	    curwp->w_dotp = lback(curwp->w_dotp);
225     }
226     curwp->w_doto = 0;
227     curwp->w_flag |= WFEDIT | WFMOVE;
228     return TRUE;
229 }
230 
231 /*ARGSUSED*/
d_flag(f,n)232 d_flag(f, n)
233 int f, n;
234 {
235   struct LINE *lp;
236   char flag = (f & FFARG) ? ' ' : 'D';
237   int nflags = 0, len;
238 
239   lp = curbp->b_linep;
240   do {
241     len = llength(lp);
242     if (len > 0 && lgetc(lp, len - 1) == '~') {
243       lputc(lp, 0, flag);
244       nflags++;
245     }
246     lp = lforw(lp);
247   } while (lp != curbp->b_linep);
248   curwp->w_flag |= WFEDIT | WFMOVE;
249   ewprintf(flag == 'D' ?
250 	   "%d backup file%s flagged." : "%d backup file%s unmarked.",
251 	   nflags, nflags == 1 ? "" : "s");
252   return TRUE;
253 }
254 
255 /*
256  * unified routine for d_findfile and d_ffotherwindow
257  */
258 
259 static
d_fileopen(f,n,popup)260 d_fileopen(f, n, popup)
261 int f, n, popup;
262 {
263     char fname[NFILEN];
264     register BUFFER *bp;
265     register int s;
266     register WINDOW *wp;
267     BUFFER *findbuffer();
268 
269     if ((s = d_makename(curwp->w_dotp, fname, sizeof(fname))) == ABORT)
270 	return FALSE;
271     if ((bp = (s ? dired_(fname) : findbuffer(fname))) == NULL)
272       return FALSE;
273 #ifdef	READONLY	/* 91.01.16  by S.Yoshida */
274     if (s) {			/* If dired buffer,	*/
275 	bp->b_flag |= BFRONLY;	/* mark as read-only.	*/
276     }
277 #endif	/* READONLY */
278     if (popup) {
279       if ((wp = popbuf(bp)) == NULL)
280 	return FALSE;
281       curbp = bp;
282       curwp = wp;
283     }
284     else {
285       curbp = bp;
286       if (showbuffer(bp, curwp, WFHARD) != TRUE)
287 	return FALSE;
288     }
289     if (bp->b_fname != NULL)
290       return TRUE;
291     s = readin(fname);
292 #ifdef	READONLY	/* 91.01.16  by S.Yoshida */
293     if (fchkreadonly(bp->b_fname)) { /* If no write permission, */
294 	    bp->b_flag |= BFRONLY;	 /* mark as read-only.      */
295 	    ewprintf("File is write protected");
296     }
297 #endif	/* READONLY */
298     return s;
299 }
300 
301 /*ARGSUSED*/
d_findfile(f,n)302 d_findfile(f, n)
303 int f, n;
304 {
305   return d_fileopen(f, n, FALSE);
306 }
307 
308 #ifdef READONLY
309 /*ARGSUSED*/
310 int
d_viewfile(f,n)311 d_viewfile(f, n)
312 int f, n;
313 {
314   int res;
315 
316   res = d_findfile(f, n);
317   if (res) {
318     curbp->b_flag |= BFRONLY; /* set read-only bit. */
319   }
320   return res;
321 }
322 #endif
323 
324 /*ARGSUSED*/
d_ffotherwindow(f,n)325 d_ffotherwindow(f, n)
326 int f, n;
327 {
328   return d_fileopen(f, n, TRUE);
329 }
330 
331 /*ARGSUSED*/
d_expunge(f,n)332 d_expunge(f, n)
333 int f, n;
334 {
335     register LINE *lp, *nlp;
336     char fname[NFILEN];
337     VOID lfree();
338 
339 #ifdef	EXTD_DIR
340     ensurecwd();
341 #endif
342 
343     for(lp = lforw(curbp->b_linep); lp != curbp->b_linep; lp = nlp) {
344 	nlp = lforw(lp);
345 	if(llength(lp) && lgetc(lp, 0) == 'D') {
346 	    switch(d_makename(lp, fname, sizeof(fname))) {
347 		case ABORT:
348 		    ewprintf("Bad line in dired buffer");
349 		    return FALSE;
350 		case FALSE:
351 		    if(unlink(fname) < 0) {
352 			ewprintf("Could not delete '%s'", fname);
353 			return FALSE;
354 		    }
355 		    break;
356 		case TRUE:
357 		    if(unlinkdir(fname) < 0) {
358 			ewprintf("Could not delete directory '%s'", fname);
359 			return FALSE;
360 		    }
361 		    break;
362 	    }
363 	    lfree(lp);
364 	    curwp->w_flag |= WFHARD;
365 	}
366     }
367     return TRUE;
368 }
369 
370 static char *
filename(path)371 filename(path)
372 char *path;
373 {
374   char *cp1;
375 
376   cp1 = path;
377   while (*cp1 != 0) {
378     ++cp1;
379   }
380   --cp1; /* insure at least 1 character ! */
381   while (cp1!= path && cp1[-1] != BDC1
382 #ifdef	BDC2
383 	 && cp1[-1] != BDC2
384 #endif
385 	 ) {
386     --cp1;
387   }
388   return cp1;
389 }
390 
391 /*ARGSUSED*/
d_copy(f,n)392 d_copy(f, n)
393 int f, n;
394 {
395     char frname[NFILEN], toname[NFILEN], *fr;
396     int stat;
397 
398 #ifdef	EXTD_DIR
399     ensurecwd();
400 #endif
401 
402     switch (d_makename(curwp->w_dotp, frname, sizeof(frname))) {
403     case TRUE:
404       ewprintf("Not a file");
405       return FALSE;
406 
407     case ABORT:
408       return FALSE;
409 
410     case FALSE:
411       /* nothing to do */
412       break;
413     }
414 
415     fr = filename(frname);
416 #ifdef	EXTD_DIR
417     edefset(curbp->b_cwd);
418 #endif
419 
420 #ifndef NO_FILECOMP	/* 90.04.04  by K.Maeda */
421     if((stat = eread("Copy %s to: ", toname, NFILEN, EFNEW | EFCR | EFFILE, fr))
422 #else	/* NO_FILECOMP */
423     if((stat = eread("Copy %s to: ", toname, NFILEN, EFNEW | EFCR, fr))
424 #endif	/* NO_FILECOMP */
425 	!= TRUE) {
426 	return stat;
427     }
428     stat = (copy(frname, toname) >= 0);
429     return stat;
430 }
431 
432 /*ARGSUSED*/
d_rename(f,n)433 d_rename(f, n)
434 int f, n;
435 {
436     char frname[NFILEN], toname[NFILEN], *fr;
437     int stat;
438 
439 #ifdef	EXTD_DIR
440     ensurecwd();
441 #endif
442 
443     switch (d_makename(curwp->w_dotp, frname, sizeof(frname))) {
444     case TRUE:
445       ewprintf("Not a file");
446       return FALSE;
447 
448     case ABORT:
449       return FALSE;
450 
451     case FALSE:
452       /* nothing to do */
453       break;
454     }
455 
456     fr = filename(frname);
457 #ifdef	EXTD_DIR
458     edefset(curbp->b_cwd);
459 #endif
460 
461 #ifndef NO_FILECOMP	/* 90.04.04  by K.Maeda */
462     if((stat = eread("Rename %s to: ", toname, NFILEN, EFNEW | EFCR | EFFILE,
463 		     fr))
464 #else	/* NO_FILECOMP */
465     if((stat = eread("Rename %s to: ", toname, NFILEN, EFNEW | EFCR, fr))
466 #endif	/* NO_FILECOMP */
467 	!= TRUE) {
468       return stat;
469     }
470     stat = (rename(frname, toname) >= 0);
471     return stat;
472 }
473 
474 /*ARGSUSED*/
475 int
d_execute(f,n)476 d_execute(f, n)
477 int f, n;
478 {
479 #ifdef WIN32
480   char fname[NFILEN];
481   register int s;
482   extern void WinExecute(char *);
483 
484   s = d_makename(curwp->w_dotp, fname, sizeof(fname));
485   if (s == ABORT) {
486     return FALSE;
487   }
488   else if (s) { /* that is, fname points to a directory */
489 #if !defined(_WIN32_WCE) || 200 <= _WIN32_WCE
490     goto noproblem;
491 #endif
492     return FALSE;
493   }
494   else {
495 noproblem:
496     WinExecute(fname);
497     return TRUE;
498   }
499 #else	/* not WIN32 */
500   return TRUE;
501 #endif	/* WIN32 */
502 }
503 
504 #endif	/* NO_DIRED */
505