Annotation of src/usr.bin/mg/dired.c, Revision 1.36
1.36 ! kjell 1: /* $OpenBSD: dired.c,v 1.35 2005/12/20 05:04:28 kjell Exp $ */
1.6 niklas 2:
1.20 kjell 3: /* This file is in the public domain. */
4:
5: /* dired module for mg 2a
6: * by Robert A. Larson
7: */
1.1 deraadt 8:
9: #include "def.h"
1.28 kjell 10: #include "funmap.h"
1.9 vincent 11: #include "kbd.h"
1.27 kjell 12:
1.12 vincent 13: #include <sys/types.h>
14: #include <sys/stat.h>
1.25 deraadt 15: #include <sys/time.h>
16: #include <sys/resource.h>
1.12 vincent 17: #include <sys/wait.h>
18:
1.24 kjell 19: #include <ctype.h>
1.12 vincent 20: #include <signal.h>
21: #include <fcntl.h>
22: #include <errno.h>
23: #include <libgen.h>
1.1 deraadt 24:
1.24 kjell 25: void dired_init(void);
1.27 kjell 26: static int dired(int, int);
27: static int d_otherwindow(int, int);
28: static int d_undel(int, int);
29: static int d_undelbak(int, int);
30: static int d_findfile(int, int);
31: static int d_ffotherwindow(int, int);
32: static int d_expunge(int, int);
33: static int d_copy(int, int);
34: static int d_del(int, int);
35: static int d_rename(int, int);
36: static int d_shell_command(int, int);
37: static int d_create_directory(int, int);
1.34 kjell 38: static int d_makename(struct line *, char *, size_t);
1.1 deraadt 39:
1.23 kjell 40: extern struct keymap_s helpmap, cXmap, metamap;
41:
42: static PF dirednul[] = {
43: setmark, /* ^@ */
44: gotobol, /* ^A */
45: backchar, /* ^B */
46: rescan, /* ^C */
47: d_del, /* ^D */
48: gotoeol, /* ^E */
49: forwchar, /* ^F */
50: ctrlg, /* ^G */
51: #ifndef NO_HELP
52: NULL, /* ^H */
53: #endif /* !NO_HELP */
1.12 vincent 54: };
55:
1.23 kjell 56: static PF diredcl[] = {
57: reposition, /* ^L */
1.15 db 58: d_findfile, /* ^M */
1.23 kjell 59: forwline, /* ^N */
60: rescan, /* ^O */
61: backline, /* ^P */
62: rescan, /* ^Q */
63: backisearch, /* ^R */
64: forwisearch, /* ^S */
65: rescan, /* ^T */
66: universal_argument, /* ^U */
67: forwpage, /* ^V */
68: rescan, /* ^W */
69: NULL /* ^X */
70: };
71:
72: static PF diredcz[] = {
73: spawncli, /* ^Z */
74: NULL, /* esc */
75: rescan, /* ^\ */
76: rescan, /* ^] */
77: rescan, /* ^^ */
78: rescan, /* ^_ */
1.27 kjell 79: forwline, /* SP */
80: d_shell_command, /* ! */
81: rescan, /* " */
82: rescan, /* # */
83: rescan, /* $ */
84: rescan, /* % */
85: rescan, /* & */
86: rescan, /* ' */
87: rescan, /* ( */
88: rescan, /* ) */
89: rescan, /* * */
90: d_create_directory /* + */
1.23 kjell 91: };
92:
93: static PF diredc[] = {
94: d_copy, /* c */
95: d_del, /* d */
96: d_findfile, /* e */
97: d_findfile /* f */
98: };
99:
100: static PF diredn[] = {
101: forwline, /* n */
102: d_ffotherwindow, /* o */
103: backline, /* p */
104: rescan, /* q */
105: d_rename, /* r */
106: rescan, /* s */
107: rescan, /* t */
108: d_undel, /* u */
109: rescan, /* v */
110: rescan, /* w */
111: d_expunge /* x */
112: };
113:
114: static PF direddl[] = {
115: d_undelbak /* del */
1.9 vincent 116: };
1.13 deraadt 117:
1.23 kjell 118: #ifndef DIRED_XMAPS
119: #define NDIRED_XMAPS 0 /* number of extra map sections */
120: #endif /* DIRED_XMAPS */
121:
122: static struct KEYMAPE (6 + NDIRED_XMAPS + IMAPEXT) diredmap = {
123: 6 + NDIRED_XMAPS,
124: 6 + NDIRED_XMAPS + IMAPEXT,
1.9 vincent 125: rescan,
126: {
1.23 kjell 127: #ifndef NO_HELP
128: {
129: CCHR('@'), CCHR('H'), dirednul, (KEYMAP *) & helpmap
130: },
131: #else /* !NO_HELP */
132: {
133: CCHR('@'), CCHR('G'), dirednul, NULL
134: },
135: #endif /* !NO_HELP */
136: {
137: CCHR('L'), CCHR('X'), diredcl, (KEYMAP *) & cXmap
138: },
139: {
1.27 kjell 140: CCHR('Z'), '+', diredcz, (KEYMAP *) & metamap
1.23 kjell 141: },
142: {
143: 'c', 'f', diredc, NULL
144: },
145: {
146: 'n', 'x', diredn, NULL
147: },
148: {
149: CCHR('?'), CCHR('?'), direddl, NULL
150: },
151: #ifdef DIRED_XMAPS
152: DIRED_XMAPS, /* map sections for dired mode keys */
153: #endif /* DIRED_XMAPS */
1.9 vincent 154: }
155: };
156:
1.23 kjell 157: void
158: dired_init(void)
159: {
1.27 kjell 160: funmap_add(dired, "dired");
161: funmap_add(d_undelbak, "dired-backup-unflag");
162: funmap_add(d_copy, "dired-copy-file");
163: funmap_add(d_expunge, "dired-do-deletions");
164: funmap_add(d_findfile, "dired-find-file");
165: funmap_add(d_ffotherwindow, "dired-find-file-other-window");
166: funmap_add(d_del, "dired-flag-file-deleted");
167: funmap_add(d_otherwindow, "dired-other-window");
168: funmap_add(d_rename, "dired-rename-file");
169: funmap_add(d_undel, "dired-unflag");
1.23 kjell 170: maps_add((KEYMAP *)&diredmap, "dired");
1.27 kjell 171: dobindkey(fundamental_map, "dired", "^Xd");
1.23 kjell 172: }
1.12 vincent 173:
1.5 millert 174: /* ARGSUSED */
175: int
1.10 vincent 176: dired(int f, int n)
1.1 deraadt 177: {
1.33 kjell 178: char dname[NFILEN], *bufp, *slash;
1.31 deraadt 179: struct buffer *bp;
1.1 deraadt 180:
1.19 cloder 181: if (curbp->b_fname && curbp->b_fname[0] != '\0') {
1.33 kjell 182: (void)strlcpy(dname, curbp->b_fname, sizeof(dname));
183: if ((slash = strrchr(dname, '/')) != NULL) {
1.19 cloder 184: *(slash + 1) = '\0';
185: }
186: } else {
1.33 kjell 187: if (getcwd(dname, sizeof(dname)) == NULL)
188: dname[0] = '\0';
1.19 cloder 189: }
190:
1.33 kjell 191: if ((bufp = eread("Dired: ", dname, NFILEN,
1.21 kjell 192: EFDEF | EFNEW | EFCR)) == NULL)
1.15 db 193: return (ABORT);
1.21 kjell 194: if (bufp[0] == '\0')
195: return (FALSE);
1.14 vincent 196: if ((bp = dired_(bufp)) == NULL)
1.15 db 197: return (FALSE);
1.23 kjell 198:
1.5 millert 199: curbp = bp;
1.15 db 200: return (showbuffer(bp, curwp, WFHARD | WFMODE));
1.1 deraadt 201: }
202:
1.5 millert 203: /* ARGSUSED */
204: int
1.10 vincent 205: d_otherwindow(int f, int n)
1.1 deraadt 206: {
1.33 kjell 207: char dname[NFILEN], *bufp, *slash;
1.31 deraadt 208: struct buffer *bp;
209: struct mgwin *wp;
1.5 millert 210:
1.23 kjell 211: if (curbp->b_fname && curbp->b_fname[0] != '\0') {
1.33 kjell 212: (void)strlcpy(dname, curbp->b_fname, sizeof(dname));
213: if ((slash = strrchr(dname, '/')) != NULL) {
1.23 kjell 214: *(slash + 1) = '\0';
215: }
216: } else {
1.33 kjell 217: if (getcwd(dname, sizeof(dname)) == NULL)
218: dname[0] = '\0';
1.23 kjell 219: }
220:
1.33 kjell 221: if ((bufp = eread("Dired other window: ", dname, NFILEN,
1.21 kjell 222: EFDEF | EFNEW | EFCR)) == NULL)
1.15 db 223: return (ABORT);
1.21 kjell 224: else if (bufp[0] == '\0')
225: return (FALSE);
1.14 vincent 226: if ((bp = dired_(bufp)) == NULL)
1.15 db 227: return (FALSE);
1.5 millert 228: if ((wp = popbuf(bp)) == NULL)
1.15 db 229: return (FALSE);
1.5 millert 230: curbp = bp;
231: curwp = wp;
1.15 db 232: return (TRUE);
1.1 deraadt 233: }
234:
1.5 millert 235: /* ARGSUSED */
236: int
1.10 vincent 237: d_del(int f, int n)
1.1 deraadt 238: {
1.5 millert 239: if (n < 0)
1.15 db 240: return (FALSE);
1.5 millert 241: while (n--) {
242: if (llength(curwp->w_dotp) > 0)
243: lputc(curwp->w_dotp, 0, 'D');
244: if (lforw(curwp->w_dotp) != curbp->b_linep)
245: curwp->w_dotp = lforw(curwp->w_dotp);
246: }
247: curwp->w_flag |= WFEDIT | WFMOVE;
248: curwp->w_doto = 0;
1.15 db 249: return (TRUE);
1.1 deraadt 250: }
251:
1.5 millert 252: /* ARGSUSED */
253: int
1.10 vincent 254: d_undel(int f, int n)
1.1 deraadt 255: {
1.5 millert 256: if (n < 0)
1.15 db 257: return (d_undelbak(f, -n));
1.5 millert 258: while (n--) {
259: if (llength(curwp->w_dotp) > 0)
260: lputc(curwp->w_dotp, 0, ' ');
261: if (lforw(curwp->w_dotp) != curbp->b_linep)
262: curwp->w_dotp = lforw(curwp->w_dotp);
263: }
264: curwp->w_flag |= WFEDIT | WFMOVE;
265: curwp->w_doto = 0;
1.15 db 266: return (TRUE);
1.1 deraadt 267: }
268:
1.5 millert 269: /* ARGSUSED */
270: int
1.10 vincent 271: d_undelbak(int f, int n)
1.1 deraadt 272: {
1.5 millert 273: if (n < 0)
1.15 db 274: return (d_undel(f, -n));
1.5 millert 275: while (n--) {
276: if (llength(curwp->w_dotp) > 0)
277: lputc(curwp->w_dotp, 0, ' ');
278: if (lback(curwp->w_dotp) != curbp->b_linep)
279: curwp->w_dotp = lback(curwp->w_dotp);
280: }
281: curwp->w_doto = 0;
282: curwp->w_flag |= WFEDIT | WFMOVE;
1.15 db 283: return (TRUE);
1.1 deraadt 284: }
285:
1.5 millert 286: /* ARGSUSED */
287: int
1.10 vincent 288: d_findfile(int f, int n)
1.1 deraadt 289: {
1.31 deraadt 290: struct buffer *bp;
291: int s;
292: char fname[NFILEN];
1.5 millert 293:
1.15 db 294: if ((s = d_makename(curwp->w_dotp, fname, sizeof(fname))) == ABORT)
295: return (FALSE);
1.12 vincent 296: if (s == TRUE)
297: bp = dired_(fname);
298: else
299: bp = findbuffer(fname);
300: if (bp == NULL)
1.15 db 301: return (FALSE);
1.5 millert 302: curbp = bp;
303: if (showbuffer(bp, curwp, WFHARD) != TRUE)
1.15 db 304: return (FALSE);
1.5 millert 305: if (bp->b_fname[0] != 0)
1.15 db 306: return (TRUE);
307: return (readin(fname));
1.1 deraadt 308: }
309:
1.5 millert 310: /* ARGSUSED */
311: int
1.10 vincent 312: d_ffotherwindow(int f, int n)
1.1 deraadt 313: {
1.31 deraadt 314: char fname[NFILEN];
315: int s;
316: struct buffer *bp;
317: struct mgwin *wp;
1.5 millert 318:
1.15 db 319: if ((s = d_makename(curwp->w_dotp, fname, sizeof(fname))) == ABORT)
320: return (FALSE);
1.5 millert 321: if ((bp = (s ? dired_(fname) : findbuffer(fname))) == NULL)
1.15 db 322: return (FALSE);
1.5 millert 323: if ((wp = popbuf(bp)) == NULL)
1.15 db 324: return (FALSE);
1.5 millert 325: curbp = bp;
326: curwp = wp;
327: if (bp->b_fname[0] != 0)
1.15 db 328: return (TRUE); /* never true for dired buffers */
329: return (readin(fname));
1.1 deraadt 330: }
331:
1.5 millert 332: /* ARGSUSED */
333: int
1.10 vincent 334: d_expunge(int f, int n)
1.1 deraadt 335: {
1.31 deraadt 336: struct line *lp, *nlp;
337: char fname[NFILEN];
1.5 millert 338:
339: for (lp = lforw(curbp->b_linep); lp != curbp->b_linep; lp = nlp) {
340: nlp = lforw(lp);
341: if (llength(lp) && lgetc(lp, 0) == 'D') {
1.15 db 342: switch (d_makename(lp, fname, sizeof(fname))) {
1.5 millert 343: case ABORT:
344: ewprintf("Bad line in dired buffer");
1.15 db 345: return (FALSE);
1.5 millert 346: case FALSE:
347: if (unlink(fname) < 0) {
1.12 vincent 348: ewprintf("Could not delete '%s'",
349: basename(fname));
1.15 db 350: return (FALSE);
1.5 millert 351: }
352: break;
353: case TRUE:
354: if (rmdir(fname) < 0) {
355: ewprintf("Could not delete directory '%s'",
1.12 vincent 356: basename(fname));
1.15 db 357: return (FALSE);
1.5 millert 358: }
359: break;
360: }
361: lfree(lp);
362: curwp->w_flag |= WFHARD;
363: }
1.1 deraadt 364: }
1.15 db 365: return (TRUE);
1.1 deraadt 366: }
367:
1.5 millert 368: /* ARGSUSED */
369: int
1.10 vincent 370: d_copy(int f, int n)
1.1 deraadt 371: {
1.14 vincent 372: char frname[NFILEN], toname[NFILEN], *bufp;
1.33 kjell 373: int ret;
1.18 cloder 374: size_t off;
1.31 deraadt 375: struct buffer *bp;
1.1 deraadt 376:
1.15 db 377: if (d_makename(curwp->w_dotp, frname, sizeof(frname)) != FALSE) {
1.5 millert 378: ewprintf("Not a file");
1.15 db 379: return (FALSE);
1.5 millert 380: }
1.15 db 381: off = strlcpy(toname, curbp->b_fname, sizeof(toname));
382: if (off >= sizeof(toname) - 1) { /* can't happen, really */
1.18 cloder 383: ewprintf("Directory name too long");
1.12 vincent 384: return (FALSE);
385: }
1.21 kjell 386: if ((bufp = eread("Copy %s to: ", toname, sizeof(toname),
387: EFDEF | EFNEW | EFCR, basename(frname))) == NULL)
1.15 db 388: return (ABORT);
1.14 vincent 389: else if (bufp[0] == '\0')
1.17 otto 390: return (FALSE);
1.33 kjell 391: ret = (copy(frname, toname) >= 0) ? TRUE : FALSE;
392: if (ret != TRUE)
393: return (ret);
1.12 vincent 394: bp = dired_(curbp->b_fname);
395: return (showbuffer(bp, curwp, WFHARD | WFMODE));
1.1 deraadt 396: }
397:
1.5 millert 398: /* ARGSUSED */
399: int
1.10 vincent 400: d_rename(int f, int n)
1.1 deraadt 401: {
1.31 deraadt 402: char frname[NFILEN], toname[NFILEN], *bufp;
1.33 kjell 403: int ret;
1.31 deraadt 404: size_t off;
405: struct buffer *bp;
1.1 deraadt 406:
1.15 db 407: if (d_makename(curwp->w_dotp, frname, sizeof(frname)) != FALSE) {
1.5 millert 408: ewprintf("Not a file");
1.15 db 409: return (FALSE);
1.5 millert 410: }
1.15 db 411: off = strlcpy(toname, curbp->b_fname, sizeof(toname));
412: if (off >= sizeof(toname) - 1) { /* can't happen, really */
1.18 cloder 413: ewprintf("Directory name too long");
1.12 vincent 414: return (FALSE);
415: }
1.21 kjell 416: if ((bufp = eread("Rename %s to: ", toname,
417: sizeof(toname), EFDEF | EFNEW | EFCR, basename(frname))) == NULL)
1.15 db 418: return (ABORT);
1.14 vincent 419: else if (bufp[0] == '\0')
1.15 db 420: return (FALSE);
1.33 kjell 421: ret = (rename(frname, toname) >= 0) ? TRUE : FALSE;
422: if (ret != TRUE)
423: return (ret);
1.12 vincent 424: bp = dired_(curbp->b_fname);
425: return (showbuffer(bp, curwp, WFHARD | WFMODE));
1.1 deraadt 426: }
1.12 vincent 427:
1.31 deraadt 428: /* ARGSUSED */
1.12 vincent 429: void
430: reaper(int signo __attribute__((unused)))
431: {
1.22 deraadt 432: int save_errno = errno, status;
1.12 vincent 433:
1.25 deraadt 434: while (waitpid(-1, &status, WNOHANG) >= 0)
1.12 vincent 435: ;
1.22 deraadt 436: errno = save_errno;
1.12 vincent 437: }
438:
439: /*
440: * Pipe the currently selected file through a shell command.
441: */
1.26 kjell 442: /* ARGSUSED */
1.12 vincent 443: int
444: d_shell_command(int f, int n)
445: {
1.15 db 446: char command[512], fname[MAXPATHLEN], buf[BUFSIZ], *bufp, *cp;
447: int infd, fds[2];
448: pid_t pid;
449: struct sigaction olda, newa;
1.31 deraadt 450: struct buffer *bp;
451: struct mgwin *wp;
1.15 db 452: FILE *fin;
1.12 vincent 453:
454: bp = bfind("*Shell Command Output*", TRUE);
455: if (bclear(bp) != TRUE)
456: return (ABORT);
457:
1.15 db 458: if (d_makename(curwp->w_dotp, fname, sizeof(fname)) != FALSE) {
1.12 vincent 459: ewprintf("bad line");
460: return (ABORT);
461: }
462:
463: command[0] = '\0';
1.21 kjell 464: if ((bufp = eread("! on %s: ", command, sizeof(command), EFNEW,
1.14 vincent 465: basename(fname))) == NULL)
1.12 vincent 466: return (ABORT);
467: infd = open(fname, O_RDONLY);
468: if (infd == -1) {
469: ewprintf("Can't open input file : %s", strerror(errno));
1.21 kjell 470: return (FALSE);
1.12 vincent 471: }
472: if (pipe(fds) == -1) {
473: ewprintf("Can't create pipe : %s", strerror(errno));
474: close(infd);
1.21 kjell 475: return (FALSE);
1.12 vincent 476: }
477:
478: newa.sa_handler = reaper;
479: newa.sa_flags = 0;
480: if (sigaction(SIGCHLD, &newa, &olda) == -1) {
481: close(infd);
482: close(fds[0]);
483: close(fds[1]);
484: return (ABORT);
485: }
486: pid = fork();
487: switch (pid) {
488: case -1:
489: ewprintf("Can't fork");
490: return (ABORT);
491: case 0:
492: close(fds[0]);
493: dup2(infd, STDIN_FILENO);
494: dup2(fds[1], STDOUT_FILENO);
495: dup2(fds[1], STDERR_FILENO);
1.14 vincent 496: execl("/bin/sh", "sh", "-c", bufp, (char *)NULL);
1.12 vincent 497: exit(1);
1.29 deraadt 498: break;
1.12 vincent 499: default:
500: close(infd);
501: close(fds[1]);
502: fin = fdopen(fds[0], "r");
503: if (fin == NULL) /* "r" is surely a valid mode! */
504: panic("can't happen");
1.15 db 505: while (fgets(buf, sizeof(buf), fin) != NULL) {
1.12 vincent 506: cp = strrchr(buf, '\n');
507: if (cp == NULL && !feof(fin)) { /* too long a line */
508: int c;
509: addlinef(bp, "%s...", buf);
510: while ((c = getc(fin)) != EOF && c != '\n')
511: ;
512: continue;
513: } else if (cp)
514: *cp = '\0';
515: addline(bp, buf);
516: }
517: fclose(fin);
518: close(fds[0]);
519: break;
520: }
521: wp = popbuf(bp);
522: if (wp == NULL)
523: return (ABORT); /* XXX - free the buffer?? */
524: curwp = wp;
525: curbp = wp->w_bufp;
526: if (sigaction(SIGCHLD, &olda, NULL) == -1)
527: ewprintf("Warning, couldn't reset previous signal handler");
528: return (TRUE);
529: }
530:
1.26 kjell 531: /* ARGSUSED */
1.12 vincent 532: int
533: d_create_directory(int f, int n)
534: {
1.15 db 535: char tocreate[MAXPATHLEN], *bufp;
1.18 cloder 536: size_t off;
1.31 deraadt 537: struct buffer *bp;
1.12 vincent 538:
1.15 db 539: off = strlcpy(tocreate, curbp->b_fname, sizeof(tocreate));
540: if (off >= sizeof(tocreate) - 1)
1.12 vincent 541: return (FALSE);
1.21 kjell 542: if ((bufp = eread("Create directory: ", tocreate,
543: sizeof(tocreate), EFDEF | EFNEW | EFCR)) == NULL)
1.14 vincent 544: return (ABORT);
545: else if (bufp[0] == '\0')
1.15 db 546: return (FALSE);
1.12 vincent 547: if (mkdir(tocreate, 0755) == -1) {
548: ewprintf("Creating directory: %s, %s", strerror(errno),
549: tocreate);
1.21 kjell 550: return (FALSE);
1.12 vincent 551: }
552: bp = dired_(curbp->b_fname);
553: return (showbuffer(bp, curwp, WFHARD | WFMODE));
554: }
1.24 kjell 555:
556: #define NAME_FIELD 8
557:
558: static int
1.34 kjell 559: d_makename(struct line *lp, char *fn, size_t len)
1.24 kjell 560: {
561: int i;
562: char *p, *ep;
563:
1.35 kjell 564: if (strlcpy(fn, curbp->b_fname, len) >= len)
565: return (FALSE);
1.24 kjell 566: if ((p = lp->l_text) == NULL)
567: return (ABORT);
568: ep = lp->l_text + llength(lp);
569: p++; /* skip action letter, if any */
570: for (i = 0; i < NAME_FIELD; i++) {
571: while (p < ep && isspace(*p))
572: p++;
573: while (p < ep && !isspace(*p))
574: p++;
575: while (p < ep && isspace(*p))
576: p++;
577: if (p == ep)
578: return (ABORT);
579: }
1.35 kjell 580: if (strlcat(fn, p, len) >= len)
581: return (FALSE);
1.24 kjell 582: return ((lgetc(lp, 2) == 'd') ? TRUE : FALSE);
583: }
584:
585: /*
1.33 kjell 586: * XXX dname needs to have enough place to store an additional '/'.
1.24 kjell 587: */
1.31 deraadt 588: struct buffer *
1.33 kjell 589: dired_(char *dname)
1.24 kjell 590: {
1.31 deraadt 591: struct buffer *bp;
1.24 kjell 592: FILE *dirpipe;
593: char line[256];
1.30 kjell 594: int len, ret;
1.24 kjell 595:
1.33 kjell 596: if ((dname = adjustname(dname)) == NULL) {
1.24 kjell 597: ewprintf("Bad directory name");
598: return (NULL);
599: }
600: /* this should not be done, instead adjustname() should get a flag */
1.33 kjell 601: len = strlen(dname);
602: if (dname[len - 1] != '/') {
603: dname[len++] = '/';
604: dname[len] = '\0';
1.24 kjell 605: }
1.33 kjell 606: if ((bp = findbuffer(dname)) == NULL) {
1.24 kjell 607: ewprintf("Could not create buffer");
608: return (NULL);
609: }
610: if (bclear(bp) != TRUE)
611: return (NULL);
612: bp->b_flag |= BFREADONLY;
1.33 kjell 613: ret = snprintf(line, sizeof(line), "ls -al %s", dname);
1.30 kjell 614: if (ret < 0 || ret >= sizeof(line)) {
1.24 kjell 615: ewprintf("Path too long");
616: return (NULL);
617: }
618: if ((dirpipe = popen(line, "r")) == NULL) {
619: ewprintf("Problem opening pipe to ls");
620: return (NULL);
621: }
622: line[0] = line[1] = ' ';
623: while (fgets(&line[2], sizeof(line) - 2, dirpipe) != NULL) {
624: line[strlen(line) - 1] = '\0'; /* remove ^J */
625: (void) addline(bp, line);
626: }
627: if (pclose(dirpipe) == -1) {
628: ewprintf("Problem closing pipe to ls : %s",
629: strerror(errno));
630: return (NULL);
631: }
632: bp->b_dotp = lforw(bp->b_linep); /* go to first line */
1.36 ! kjell 633: (void)strlcpy(bp->b_fname, dname, sizeof(bp->b_fname));
! 634: (void)strlcpy(bp->b_cwd, dname, sizeof(bp->b_cwd));
1.24 kjell 635: if ((bp->b_modes[1] = name_mode("dired")) == NULL) {
636: bp->b_modes[0] = name_mode("fundamental");
637: ewprintf("Could not find mode dired");
638: return (NULL);
639: }
640: bp->b_nmodes = 1;
641: return (bp);
642: }