Annotation of src/usr.bin/mg/dired.c, Revision 1.42
1.42 ! ray 1: /* $OpenBSD: dired.c,v 1.41 2006/07/25 08:27:09 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.37 kjell 200: return (showbuffer(bp, curwp, WFFULL | 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');
1.40 kjell 244: if (lforw(curwp->w_dotp) != curbp->b_headp)
1.5 millert 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, ' ');
1.40 kjell 261: if (lforw(curwp->w_dotp) != curbp->b_headp)
1.5 millert 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, ' ');
1.40 kjell 278: if (lback(curwp->w_dotp) != curbp->b_headp)
1.5 millert 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;
1.37 kjell 303: if (showbuffer(bp, curwp, WFFULL) != 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:
1.41 kjell 339: for (lp = bfirstlp(curbp); lp != curbp->b_headp; lp = nlp) {
1.5 millert 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);
1.39 kjell 362: curwp->w_bufp->b_lines--;
1.37 kjell 363: curwp->w_flag |= WFFULL;
1.5 millert 364: }
1.1 deraadt 365: }
1.15 db 366: return (TRUE);
1.1 deraadt 367: }
368:
1.5 millert 369: /* ARGSUSED */
370: int
1.10 vincent 371: d_copy(int f, int n)
1.1 deraadt 372: {
1.14 vincent 373: char frname[NFILEN], toname[NFILEN], *bufp;
1.33 kjell 374: int ret;
1.18 cloder 375: size_t off;
1.31 deraadt 376: struct buffer *bp;
1.1 deraadt 377:
1.15 db 378: if (d_makename(curwp->w_dotp, frname, sizeof(frname)) != FALSE) {
1.5 millert 379: ewprintf("Not a file");
1.15 db 380: return (FALSE);
1.5 millert 381: }
1.15 db 382: off = strlcpy(toname, curbp->b_fname, sizeof(toname));
383: if (off >= sizeof(toname) - 1) { /* can't happen, really */
1.18 cloder 384: ewprintf("Directory name too long");
1.12 vincent 385: return (FALSE);
386: }
1.21 kjell 387: if ((bufp = eread("Copy %s to: ", toname, sizeof(toname),
388: EFDEF | EFNEW | EFCR, basename(frname))) == NULL)
1.15 db 389: return (ABORT);
1.14 vincent 390: else if (bufp[0] == '\0')
1.17 otto 391: return (FALSE);
1.33 kjell 392: ret = (copy(frname, toname) >= 0) ? TRUE : FALSE;
393: if (ret != TRUE)
394: return (ret);
1.12 vincent 395: bp = dired_(curbp->b_fname);
1.37 kjell 396: return (showbuffer(bp, curwp, WFFULL | WFMODE));
1.1 deraadt 397: }
398:
1.5 millert 399: /* ARGSUSED */
400: int
1.10 vincent 401: d_rename(int f, int n)
1.1 deraadt 402: {
1.31 deraadt 403: char frname[NFILEN], toname[NFILEN], *bufp;
1.33 kjell 404: int ret;
1.31 deraadt 405: size_t off;
406: struct buffer *bp;
1.1 deraadt 407:
1.15 db 408: if (d_makename(curwp->w_dotp, frname, sizeof(frname)) != FALSE) {
1.5 millert 409: ewprintf("Not a file");
1.15 db 410: return (FALSE);
1.5 millert 411: }
1.15 db 412: off = strlcpy(toname, curbp->b_fname, sizeof(toname));
413: if (off >= sizeof(toname) - 1) { /* can't happen, really */
1.18 cloder 414: ewprintf("Directory name too long");
1.12 vincent 415: return (FALSE);
416: }
1.21 kjell 417: if ((bufp = eread("Rename %s to: ", toname,
418: sizeof(toname), EFDEF | EFNEW | EFCR, basename(frname))) == NULL)
1.15 db 419: return (ABORT);
1.14 vincent 420: else if (bufp[0] == '\0')
1.15 db 421: return (FALSE);
1.33 kjell 422: ret = (rename(frname, toname) >= 0) ? TRUE : FALSE;
423: if (ret != TRUE)
424: return (ret);
1.12 vincent 425: bp = dired_(curbp->b_fname);
1.37 kjell 426: return (showbuffer(bp, curwp, WFFULL | WFMODE));
1.1 deraadt 427: }
1.12 vincent 428:
1.31 deraadt 429: /* ARGSUSED */
1.12 vincent 430: void
431: reaper(int signo __attribute__((unused)))
432: {
1.22 deraadt 433: int save_errno = errno, status;
1.12 vincent 434:
1.25 deraadt 435: while (waitpid(-1, &status, WNOHANG) >= 0)
1.12 vincent 436: ;
1.22 deraadt 437: errno = save_errno;
1.12 vincent 438: }
439:
440: /*
441: * Pipe the currently selected file through a shell command.
442: */
1.26 kjell 443: /* ARGSUSED */
1.12 vincent 444: int
445: d_shell_command(int f, int n)
446: {
1.15 db 447: char command[512], fname[MAXPATHLEN], buf[BUFSIZ], *bufp, *cp;
448: int infd, fds[2];
449: pid_t pid;
450: struct sigaction olda, newa;
1.31 deraadt 451: struct buffer *bp;
452: struct mgwin *wp;
1.15 db 453: FILE *fin;
1.12 vincent 454:
455: bp = bfind("*Shell Command Output*", TRUE);
456: if (bclear(bp) != TRUE)
457: return (ABORT);
458:
1.15 db 459: if (d_makename(curwp->w_dotp, fname, sizeof(fname)) != FALSE) {
1.12 vincent 460: ewprintf("bad line");
461: return (ABORT);
462: }
463:
464: command[0] = '\0';
1.21 kjell 465: if ((bufp = eread("! on %s: ", command, sizeof(command), EFNEW,
1.14 vincent 466: basename(fname))) == NULL)
1.12 vincent 467: return (ABORT);
468: infd = open(fname, O_RDONLY);
469: if (infd == -1) {
470: ewprintf("Can't open input file : %s", strerror(errno));
1.21 kjell 471: return (FALSE);
1.12 vincent 472: }
473: if (pipe(fds) == -1) {
474: ewprintf("Can't create pipe : %s", strerror(errno));
475: close(infd);
1.21 kjell 476: return (FALSE);
1.12 vincent 477: }
478:
479: newa.sa_handler = reaper;
480: newa.sa_flags = 0;
481: if (sigaction(SIGCHLD, &newa, &olda) == -1) {
482: close(infd);
483: close(fds[0]);
484: close(fds[1]);
485: return (ABORT);
486: }
487: pid = fork();
488: switch (pid) {
489: case -1:
490: ewprintf("Can't fork");
491: return (ABORT);
492: case 0:
493: close(fds[0]);
494: dup2(infd, STDIN_FILENO);
495: dup2(fds[1], STDOUT_FILENO);
496: dup2(fds[1], STDERR_FILENO);
1.14 vincent 497: execl("/bin/sh", "sh", "-c", bufp, (char *)NULL);
1.12 vincent 498: exit(1);
1.29 deraadt 499: break;
1.12 vincent 500: default:
501: close(infd);
502: close(fds[1]);
503: fin = fdopen(fds[0], "r");
504: if (fin == NULL) /* "r" is surely a valid mode! */
505: panic("can't happen");
1.15 db 506: while (fgets(buf, sizeof(buf), fin) != NULL) {
1.12 vincent 507: cp = strrchr(buf, '\n');
508: if (cp == NULL && !feof(fin)) { /* too long a line */
509: int c;
510: addlinef(bp, "%s...", buf);
511: while ((c = getc(fin)) != EOF && c != '\n')
512: ;
513: continue;
514: } else if (cp)
515: *cp = '\0';
516: addline(bp, buf);
517: }
518: fclose(fin);
519: close(fds[0]);
520: break;
521: }
522: wp = popbuf(bp);
523: if (wp == NULL)
524: return (ABORT); /* XXX - free the buffer?? */
525: curwp = wp;
526: curbp = wp->w_bufp;
527: if (sigaction(SIGCHLD, &olda, NULL) == -1)
528: ewprintf("Warning, couldn't reset previous signal handler");
529: return (TRUE);
530: }
531:
1.26 kjell 532: /* ARGSUSED */
1.12 vincent 533: int
534: d_create_directory(int f, int n)
535: {
1.15 db 536: char tocreate[MAXPATHLEN], *bufp;
1.18 cloder 537: size_t off;
1.31 deraadt 538: struct buffer *bp;
1.12 vincent 539:
1.15 db 540: off = strlcpy(tocreate, curbp->b_fname, sizeof(tocreate));
541: if (off >= sizeof(tocreate) - 1)
1.12 vincent 542: return (FALSE);
1.21 kjell 543: if ((bufp = eread("Create directory: ", tocreate,
544: sizeof(tocreate), EFDEF | EFNEW | EFCR)) == NULL)
1.14 vincent 545: return (ABORT);
546: else if (bufp[0] == '\0')
1.15 db 547: return (FALSE);
1.12 vincent 548: if (mkdir(tocreate, 0755) == -1) {
549: ewprintf("Creating directory: %s, %s", strerror(errno),
550: tocreate);
1.21 kjell 551: return (FALSE);
1.12 vincent 552: }
553: bp = dired_(curbp->b_fname);
1.37 kjell 554: return (showbuffer(bp, curwp, WFFULL | WFMODE));
1.12 vincent 555: }
1.24 kjell 556:
557: #define NAME_FIELD 8
558:
559: static int
1.34 kjell 560: d_makename(struct line *lp, char *fn, size_t len)
1.24 kjell 561: {
562: int i;
563: char *p, *ep;
564:
1.35 kjell 565: if (strlcpy(fn, curbp->b_fname, len) >= len)
566: return (FALSE);
1.24 kjell 567: if ((p = lp->l_text) == NULL)
568: return (ABORT);
569: ep = lp->l_text + llength(lp);
570: p++; /* skip action letter, if any */
571: for (i = 0; i < NAME_FIELD; i++) {
572: while (p < ep && isspace(*p))
573: p++;
574: while (p < ep && !isspace(*p))
575: p++;
576: while (p < ep && isspace(*p))
577: p++;
578: if (p == ep)
579: return (ABORT);
580: }
1.35 kjell 581: if (strlcat(fn, p, len) >= len)
582: return (FALSE);
1.24 kjell 583: return ((lgetc(lp, 2) == 'd') ? TRUE : FALSE);
584: }
585:
586: /*
1.33 kjell 587: * XXX dname needs to have enough place to store an additional '/'.
1.24 kjell 588: */
1.31 deraadt 589: struct buffer *
1.33 kjell 590: dired_(char *dname)
1.24 kjell 591: {
1.31 deraadt 592: struct buffer *bp;
1.24 kjell 593: FILE *dirpipe;
594: char line[256];
1.30 kjell 595: int len, ret;
1.24 kjell 596:
1.38 jason 597: if ((dname = adjustname(dname, FALSE)) == NULL) {
1.24 kjell 598: ewprintf("Bad directory name");
599: return (NULL);
600: }
601: /* this should not be done, instead adjustname() should get a flag */
1.33 kjell 602: len = strlen(dname);
603: if (dname[len - 1] != '/') {
604: dname[len++] = '/';
605: dname[len] = '\0';
1.24 kjell 606: }
1.33 kjell 607: if ((bp = findbuffer(dname)) == NULL) {
1.24 kjell 608: ewprintf("Could not create buffer");
609: return (NULL);
610: }
611: if (bclear(bp) != TRUE)
612: return (NULL);
613: bp->b_flag |= BFREADONLY;
1.33 kjell 614: ret = snprintf(line, sizeof(line), "ls -al %s", dname);
1.30 kjell 615: if (ret < 0 || ret >= sizeof(line)) {
1.24 kjell 616: ewprintf("Path too long");
617: return (NULL);
618: }
619: if ((dirpipe = popen(line, "r")) == NULL) {
620: ewprintf("Problem opening pipe to ls");
621: return (NULL);
622: }
623: line[0] = line[1] = ' ';
624: while (fgets(&line[2], sizeof(line) - 2, dirpipe) != NULL) {
1.42 ! ray 625: char *p;
! 626:
! 627: if ((p = strchr(line, '\n')) != NULL)
! 628: *p = '\0'; /* remove ^J */
1.24 kjell 629: (void) addline(bp, line);
630: }
631: if (pclose(dirpipe) == -1) {
632: ewprintf("Problem closing pipe to ls : %s",
633: strerror(errno));
634: return (NULL);
635: }
1.41 kjell 636: bp->b_dotp = bfirstlp(bp);
1.36 kjell 637: (void)strlcpy(bp->b_fname, dname, sizeof(bp->b_fname));
638: (void)strlcpy(bp->b_cwd, dname, sizeof(bp->b_cwd));
1.24 kjell 639: if ((bp->b_modes[1] = name_mode("dired")) == NULL) {
640: bp->b_modes[0] = name_mode("fundamental");
641: ewprintf("Could not find mode dired");
642: return (NULL);
643: }
644: bp->b_nmodes = 1;
645: return (bp);
646: }