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