[BACK]Return to dired.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

Annotation of src/usr.bin/mg/dired.c, Revision 1.13

1.13    ! deraadt     1: /*     $OpenBSD: dired.c,v 1.12 2003/08/15 23:23:18 vincent Exp $      */
1.6       niklas      2:
1.5       millert     3: /* dired module for mg 2a       */
                      4: /* by Robert A. Larson          */
1.1       deraadt     5:
                      6: #include "def.h"
1.9       vincent     7: #include "kbd.h"
1.12      vincent     8: #include <sys/types.h>
                      9: #include <sys/stat.h>
                     10: #include <sys/wait.h>
                     11:
                     12: #include <signal.h>
                     13: #include <fcntl.h>
                     14: #include <errno.h>
                     15: #include <libgen.h>
1.1       deraadt    16:
                     17: #ifndef NO_DIRED
1.11      vincent    18:
                     19: int d_findfile(int, int);
1.1       deraadt    20:
1.12      vincent    21: static PF dired_cmds_1[] = {
                     22:        forwline,               /* space */
                     23:        d_shell_command,        /* ! */
                     24:        rescan,                 /* " */
                     25:        rescan,                 /* # */
                     26:        rescan,                 /* $ */
                     27:        rescan,                 /* % */
                     28:        rescan,                 /* & */
                     29:        rescan,                 /* ' */
                     30:        rescan,                 /* ( */
                     31:        rescan,                 /* ) */
                     32:        rescan,                 /* * */
                     33:        d_create_directory,     /* + */
                     34: };
                     35:
                     36: static PF dired_cmds_2[] = {
                     37:        rescan, /* a */
                     38:        rescan, /* b */
                     39:        rescan, /* c */
                     40:        rescan, /* d */
                     41:        d_findfile, /* e */
                     42:        d_findfile, /* f */
                     43:        rescan, /* g */
                     44:        rescan, /* h */
                     45:        rescan, /* i */
                     46:        rescan, /* j */
                     47:        rescan, /* k */
                     48:        rescan, /* l */
                     49:        rescan, /* m */
                     50:        forwline, /* n */
                     51:        d_ffotherwindow, /* o */
                     52:        rescan, /* p */
                     53:        rescan, /* q */
                     54:        rescan, /* r */
                     55:        rescan, /* s */
                     56:        rescan, /* t */
                     57:        rescan, /* u */
                     58:        d_findfile, /* v */
                     59:        rescan, /* w */
                     60:        d_expunge, /* x */
                     61:        rescan, /* y */
                     62:        rescan, /* z */
                     63: };
                     64:
                     65: static PF dired_cmds_3[] = {
                     66:        rescan, /* A */
                     67:        rescan, /* B */
                     68:        d_copy, /* C */
                     69:        d_del,  /* D */
                     70:        rescan, /* E */
                     71:        rescan, /* F */
                     72:        rescan, /* G */
                     73:        rescan, /* H */
                     74:        rescan, /* I */
                     75:        rescan, /* J */
                     76:        rescan, /* K */
                     77:        rescan, /* L */
                     78:        rescan, /* M */
                     79:        rescan, /* N */
                     80:        rescan, /* O */
                     81:        rescan, /* P */
                     82:        rescan, /* Q */
                     83:        d_rename, /* R */
                     84:        rescan, /* S */
                     85:        rescan, /* T */
                     86:        rescan, /* U */
                     87:        d_findfile, /* V */
                     88:        rescan, /* W */
                     89:        d_expunge, /* X */
                     90:        rescan, /* Y */
                     91:        rescan, /* Z */
                     92: };
                     93:
1.9       vincent    94: static PF dired_pf[] = {
1.12      vincent    95:        d_findfile,     /* ^M */
                     96:        rescan,         /* ^N */
                     97:        d_findfile,     /* ^O */
1.9       vincent    98: };
1.13    ! deraadt    99:
1.12      vincent   100: static struct KEYMAPE (4 + IMAPEXT) diredmap = {
                    101:        4,
                    102:        4 + IMAPEXT,
1.9       vincent   103:        rescan,
                    104:        {
1.12      vincent   105:                { CCHR('M'), CCHR('O'), dired_pf, NULL },
                    106:                { ' ', '+', dired_cmds_1, NULL },
                    107:                { 'A', 'Z', dired_cmds_3, NULL },
                    108:                { 'a', 'z', dired_cmds_2, NULL }
1.9       vincent   109:        }
                    110: };
                    111:
1.12      vincent   112:
1.5       millert   113: /* ARGSUSED */
                    114: int
1.10      vincent   115: dired(int f, int n)
1.1       deraadt   116: {
1.9       vincent   117:        static int inited = 0;
1.7       mickey    118:        char    dirname[NFILEN];
1.5       millert   119:        BUFFER *bp;
1.1       deraadt   120:
1.9       vincent   121:        if (inited == 0) {
                    122:                maps_add((KEYMAP *)&diredmap, "dired");
                    123:                inited = 1;
                    124:        }
                    125:
1.5       millert   126:        dirname[0] = '\0';
                    127:        if (eread("Dired: ", dirname, NFILEN, EFNEW | EFCR) == ABORT)
                    128:                return ABORT;
                    129:        if ((bp = dired_(dirname)) == NULL)
                    130:                return FALSE;
1.9       vincent   131:        bp->b_modes[0] = name_mode("fundamental");
                    132:        bp->b_modes[1] = name_mode("dired");
                    133:        bp->b_nmodes = 1;
1.5       millert   134:        curbp = bp;
                    135:        return showbuffer(bp, curwp, WFHARD | WFMODE);
1.1       deraadt   136: }
                    137:
1.5       millert   138: /* ARGSUSED */
                    139: int
1.10      vincent   140: d_otherwindow(int f, int n)
1.1       deraadt   141: {
1.7       mickey    142:        char    dirname[NFILEN];
                    143:        BUFFER  *bp;
                    144:        MGWIN   *wp;
1.5       millert   145:
                    146:        dirname[0] = '\0';
1.12      vincent   147:        if (eread("Dired other window: ", dirname, NFILEN, EFNEW | EFCR)
                    148:            == ABORT)
1.5       millert   149:                return ABORT;
                    150:        if ((bp = dired_(dirname)) == NULL)
                    151:                return FALSE;
                    152:        if ((wp = popbuf(bp)) == NULL)
                    153:                return FALSE;
                    154:        curbp = bp;
                    155:        curwp = wp;
                    156:        return TRUE;
1.1       deraadt   157: }
                    158:
1.5       millert   159: /* ARGSUSED */
                    160: int
1.10      vincent   161: d_del(int f, int n)
1.1       deraadt   162: {
1.5       millert   163:        if (n < 0)
                    164:                return FALSE;
                    165:        while (n--) {
                    166:                if (llength(curwp->w_dotp) > 0)
                    167:                        lputc(curwp->w_dotp, 0, 'D');
                    168:                if (lforw(curwp->w_dotp) != curbp->b_linep)
                    169:                        curwp->w_dotp = lforw(curwp->w_dotp);
                    170:        }
                    171:        curwp->w_flag |= WFEDIT | WFMOVE;
                    172:        curwp->w_doto = 0;
                    173:        return TRUE;
1.1       deraadt   174: }
                    175:
1.5       millert   176: /* ARGSUSED */
                    177: int
1.10      vincent   178: d_undel(int f, int n)
1.1       deraadt   179: {
1.5       millert   180:        if (n < 0)
                    181:                return d_undelbak(f, -n);
                    182:        while (n--) {
                    183:                if (llength(curwp->w_dotp) > 0)
                    184:                        lputc(curwp->w_dotp, 0, ' ');
                    185:                if (lforw(curwp->w_dotp) != curbp->b_linep)
                    186:                        curwp->w_dotp = lforw(curwp->w_dotp);
                    187:        }
                    188:        curwp->w_flag |= WFEDIT | WFMOVE;
                    189:        curwp->w_doto = 0;
                    190:        return TRUE;
1.1       deraadt   191: }
                    192:
1.5       millert   193: /* ARGSUSED */
                    194: int
1.10      vincent   195: d_undelbak(int f, int n)
1.1       deraadt   196: {
1.5       millert   197:        if (n < 0)
                    198:                return d_undel(f, -n);
                    199:        while (n--) {
                    200:                if (llength(curwp->w_dotp) > 0)
                    201:                        lputc(curwp->w_dotp, 0, ' ');
                    202:                if (lback(curwp->w_dotp) != curbp->b_linep)
                    203:                        curwp->w_dotp = lback(curwp->w_dotp);
                    204:        }
                    205:        curwp->w_doto = 0;
                    206:        curwp->w_flag |= WFEDIT | WFMOVE;
                    207:        return TRUE;
1.1       deraadt   208: }
                    209:
1.5       millert   210: /* ARGSUSED */
                    211: int
1.10      vincent   212: d_findfile(int f, int n)
1.1       deraadt   213: {
1.5       millert   214:        BUFFER *bp;
1.7       mickey    215:        int     s;
                    216:        char    fname[NFILEN];
1.5       millert   217:
1.8       vincent   218:        if ((s = d_makename(curwp->w_dotp, fname, sizeof fname)) == ABORT)
1.5       millert   219:                return FALSE;
1.12      vincent   220:        if (s == TRUE)
                    221:                bp = dired_(fname);
                    222:        else
                    223:                bp = findbuffer(fname);
                    224:        if (bp == NULL)
1.5       millert   225:                return FALSE;
                    226:        curbp = bp;
                    227:        if (showbuffer(bp, curwp, WFHARD) != TRUE)
                    228:                return FALSE;
                    229:        if (bp->b_fname[0] != 0)
                    230:                return TRUE;
                    231:        return readin(fname);
1.1       deraadt   232: }
                    233:
1.5       millert   234: /* ARGSUSED */
                    235: int
1.10      vincent   236: d_ffotherwindow(int f, int n)
1.1       deraadt   237: {
1.7       mickey    238:        char    fname[NFILEN];
                    239:        int     s;
1.5       millert   240:        BUFFER *bp;
                    241:        MGWIN  *wp;
                    242:
1.8       vincent   243:        if ((s = d_makename(curwp->w_dotp, fname, sizeof fname)) == ABORT)
1.5       millert   244:                return FALSE;
                    245:        if ((bp = (s ? dired_(fname) : findbuffer(fname))) == NULL)
                    246:                return FALSE;
                    247:        if ((wp = popbuf(bp)) == NULL)
                    248:                return FALSE;
                    249:        curbp = bp;
                    250:        curwp = wp;
                    251:        if (bp->b_fname[0] != 0)
                    252:                return TRUE;    /* never true for dired buffers */
                    253:        return readin(fname);
1.1       deraadt   254: }
                    255:
1.5       millert   256: /* ARGSUSED */
                    257: int
1.10      vincent   258: d_expunge(int f, int n)
1.1       deraadt   259: {
1.7       mickey    260:        LINE    *lp, *nlp;
                    261:        char    fname[NFILEN];
1.5       millert   262:
                    263:        for (lp = lforw(curbp->b_linep); lp != curbp->b_linep; lp = nlp) {
                    264:                nlp = lforw(lp);
                    265:                if (llength(lp) && lgetc(lp, 0) == 'D') {
1.8       vincent   266:                        switch (d_makename(lp, fname, sizeof fname)) {
1.5       millert   267:                        case ABORT:
                    268:                                ewprintf("Bad line in dired buffer");
                    269:                                return FALSE;
                    270:                        case FALSE:
                    271:                                if (unlink(fname) < 0) {
1.12      vincent   272:                                        ewprintf("Could not delete '%s'",
                    273:                                            basename(fname));
1.5       millert   274:                                        return FALSE;
                    275:                                }
                    276:                                break;
                    277:                        case TRUE:
                    278:                                if (rmdir(fname) < 0) {
                    279:                                        ewprintf("Could not delete directory '%s'",
1.12      vincent   280:                                            basename(fname));
1.5       millert   281:                                        return FALSE;
                    282:                                }
                    283:                                break;
                    284:                        }
                    285:                        lfree(lp);
                    286:                        curwp->w_flag |= WFHARD;
                    287:                }
1.1       deraadt   288:        }
1.5       millert   289:        return TRUE;
1.1       deraadt   290: }
                    291:
1.12      vincent   292:
1.5       millert   293: /* ARGSUSED */
                    294: int
1.10      vincent   295: d_copy(int f, int n)
1.1       deraadt   296: {
1.7       mickey    297:        char    frname[NFILEN], toname[NFILEN];
1.12      vincent   298:        int     stat, off;
                    299:        BUFFER *bp;
1.1       deraadt   300:
1.8       vincent   301:        if (d_makename(curwp->w_dotp, frname, sizeof frname) != FALSE) {
1.5       millert   302:                ewprintf("Not a file");
                    303:                return FALSE;
                    304:        }
1.12      vincent   305:        off = strlcpy(toname, curbp->b_fname, sizeof toname);
                    306:        if (off >= sizeof toname - 1) { /* can't happen, really */
                    307:                ewprintf("too long directory name");
                    308:                return (FALSE);
                    309:        }
                    310:        if ((stat = eread("Copy %s to: ", toname + off, sizeof toname - off,
                    311:            EFNEW | EFCR, basename(frname))) != TRUE)
                    312:                return (stat);
                    313:        stat = (copy(frname, toname) >= 0) ? TRUE : FALSE;
                    314:        if (stat != TRUE)
                    315:                return (stat);
                    316:        bp = dired_(curbp->b_fname);
                    317:        return (showbuffer(bp, curwp, WFHARD | WFMODE));
1.1       deraadt   318: }
                    319:
1.5       millert   320: /* ARGSUSED */
                    321: int
1.10      vincent   322: d_rename(int f, int n)
1.1       deraadt   323: {
1.5       millert   324:        char    frname[NFILEN], toname[NFILEN];
1.12      vincent   325:        int     stat, off;
                    326:        BUFFER *bp;
1.1       deraadt   327:
1.8       vincent   328:        if (d_makename(curwp->w_dotp, frname, sizeof frname) != FALSE) {
1.5       millert   329:                ewprintf("Not a file");
                    330:                return FALSE;
                    331:        }
1.12      vincent   332:        off = strlcpy(toname, curbp->b_fname, sizeof toname);
                    333:        if (off >= sizeof toname - 1) { /* can't happen, really */
                    334:                ewprintf("too long directory name");
                    335:                return (FALSE);
                    336:        }
                    337:        if ((stat = eread("Rename %s to: ", toname + off,
                    338:            sizeof toname - off, EFNEW | EFCR, basename(frname))) != TRUE)
1.5       millert   339:                return stat;
1.12      vincent   340:        stat = (rename(frname, toname) >= 0) ? TRUE : FALSE;
                    341:        if (stat != TRUE)
                    342:                return (stat);
                    343:        bp = dired_(curbp->b_fname);
                    344:        return (showbuffer(bp, curwp, WFHARD | WFMODE));
1.1       deraadt   345: }
                    346: #endif
1.12      vincent   347:
                    348: void
                    349: reaper(int signo __attribute__((unused)))
                    350: {
                    351:        pid_t ret;
                    352:        int status;
                    353:
                    354:        while ((ret = waitpid(-1, &status, WNOHANG)) >= 0)
                    355:                ;
                    356: }
                    357:
                    358: /*
                    359:  * Pipe the currently selected file through a shell command.
                    360:  */
                    361: int
                    362: d_shell_command(int f, int n)
                    363: {
                    364:        char command[512], fname[MAXPATHLEN], buf[BUFSIZ], *cp;
                    365:        int infd, fds[2];
                    366:        pid_t pid;
                    367:        struct sigaction olda, newa;
                    368:        BUFFER *bp;
                    369:        MGWIN *wp;
                    370:        FILE *fin;
                    371:
                    372:        bp = bfind("*Shell Command Output*", TRUE);
                    373:        if (bclear(bp) != TRUE)
                    374:                return (ABORT);
                    375:
                    376:        if (d_makename(curwp->w_dotp, fname, sizeof fname) != FALSE) {
                    377:                ewprintf("bad line");
                    378:                return (ABORT);
                    379:        }
                    380:
                    381:        command[0] = '\0';
                    382:        if (eread("! on %s: ", command, sizeof command, 0,
                    383:            basename(fname)) == ABORT)
                    384:                return (ABORT);
                    385:        infd = open(fname, O_RDONLY);
                    386:        if (infd == -1) {
                    387:                ewprintf("Can't open input file : %s", strerror(errno));
                    388:                return (ABORT);
                    389:        }
                    390:        if (pipe(fds) == -1) {
                    391:                ewprintf("Can't create pipe : %s", strerror(errno));
                    392:                close(infd);
                    393:                return (ABORT);
                    394:        }
                    395:
                    396:        newa.sa_handler = reaper;
                    397:        newa.sa_flags = 0;
                    398:        if (sigaction(SIGCHLD, &newa, &olda) == -1) {
                    399:                close(infd);
                    400:                close(fds[0]);
                    401:                close(fds[1]);
                    402:                return (ABORT);
                    403:        }
                    404:        pid = fork();
                    405:        switch (pid) {
                    406:        case -1:
                    407:                ewprintf("Can't fork");
                    408:                return (ABORT);
                    409:        case 0:
                    410:                close(fds[0]);
                    411:                dup2(infd, STDIN_FILENO);
                    412:                dup2(fds[1], STDOUT_FILENO);
                    413:                dup2(fds[1], STDERR_FILENO);
                    414:                execl("/bin/sh", "sh", "-c", command, (char *)NULL);
                    415:                exit(1);
                    416:        default:
                    417:                close(infd);
                    418:                close(fds[1]);
                    419:                fin = fdopen(fds[0], "r");
                    420:                if (fin == NULL)        /* "r" is surely a valid mode! */
                    421:                        panic("can't happen");
                    422:                while (fgets(buf, sizeof buf, fin) != NULL) {
                    423:                        cp = strrchr(buf, '\n');
                    424:                        if (cp == NULL && !feof(fin)) { /* too long a line */
                    425:                                int c;
                    426:                                addlinef(bp, "%s...", buf);
                    427:                                while ((c = getc(fin)) != EOF && c != '\n')
                    428:                                        ;
                    429:                                continue;
                    430:                        } else if (cp)
                    431:                                *cp = '\0';
                    432:                        addline(bp, buf);
                    433:                }
                    434:                fclose(fin);
                    435:                close(fds[0]);
                    436:                break;
                    437:        }
                    438:        wp = popbuf(bp);
                    439:        if (wp == NULL)
                    440:                return (ABORT); /* XXX - free the buffer?? */
                    441:        curwp = wp;
                    442:        curbp = wp->w_bufp;
                    443:        if (sigaction(SIGCHLD, &olda, NULL) == -1)
                    444:                ewprintf("Warning, couldn't reset previous signal handler");
                    445:        return (TRUE);
                    446: }
                    447:
                    448: int
                    449: d_create_directory(int f, int n)
                    450: {
                    451:        char tocreate[MAXPATHLEN], off;
                    452:        int stat;
                    453:        BUFFER *bp;
                    454:
                    455:        off = strlcpy(tocreate, curbp->b_fname, sizeof tocreate);
                    456:        if (off >= sizeof tocreate - 1)
                    457:                return (FALSE);
                    458:        if ((stat = ereply("Create directory: ", tocreate + off,
                    459:            sizeof tocreate - off))
                    460:            != TRUE)
                    461:                return (stat);
                    462:        if (mkdir(tocreate, 0755) == -1) {
                    463:                ewprintf("Creating directory: %s, %s", strerror(errno),
                    464:                    tocreate);
                    465:                return (ABORT);
                    466:        }
                    467:        bp = dired_(curbp->b_fname);
                    468:        return (showbuffer(bp, curwp, WFHARD | WFMODE));
                    469: }