sfm

Simple file manager
git clone git://git.christosmarg.xyz/sfm.git
Log | Files | Refs | README | LICENSE

commit d8464186980d6faa6e11810dee73db3a8e1d1d65
parent 8868b3cf35b3dde3c97cf6222976786757f65bb9
Author: Christos Margiolis <christos@margiolis.net>
Date:   Wed, 26 May 2021 19:03:23 +0300

changed mail

Diffstat:
MLICENSE | 2+-
MMakefile | 31++++++++++++++-----------------
Mconfig.h | 62++++++++++++++++++++++++++++++--------------------------------
Mconfig.mk | 21+++++----------------
Msfm.1 | 4++--
Msfm.c | 225+++++++++++++++++++++++++++++++++++++------------------------------------------
6 files changed, 158 insertions(+), 187 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -1,6 +1,6 @@ MIT License -(c) 2020-Present Christos Margiolis <christos@christosmarg.xyz> +(c) 2020-Present Christos Margiolis <christos@margiolis.net> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in diff --git a/Makefile b/Makefile @@ -19,8 +19,6 @@ options: @echo "LDFLAGS = ${LDFLAGS}" @echo "CC = ${CC}" -${OBJ}: config.h config.mk - ${BIN}: ${OBJ} ${CC} ${LDFLAGS} ${OBJ} -o $@ @@ -28,29 +26,28 @@ ${BIN}: ${OBJ} ${CC} -c ${CFLAGS} $< dist: clean - ${MKDIR} ${DIST} - ${CP} -R config.h config.mk Makefile ${SRC} ${DIST} - ${TAR} ${DIST}.tar ${DIST} - ${GZIP} ${DIST}.tar - ${RM_DIR} ${DIST} + mkdir -p ${DIST} + cp -R config.h config.mk LICENSE Makefile README sfm.1 sfm.c ${DIST} + tar -cf ${DIST}.tar ${DIST} + gzip ${DIST}.tar + rm -rf ${DIST} run: ./${BIN} install: all - ${MKDIR} ${DESTDIR}${BIN_DIR} ${DESTDIR}${MAN_DIR} - ${MKDIR} ${DESTDIR}${BIN_DIR} - ${CP} ${BIN} ${BIN_DIR} - ${CP} ${MAN1} ${DESTDIR}${MAN_DIR} - sed "s/VERSION/${VERSION}/g" < ${MAN1} > ${DESTDIR}${MAN_DIR}/${MAN1} - chmod 755 ${DESTDIR}${BIN_DIR}/${BIN} - chmod 644 ${DESTDIR}${MAN_DIR}/${MAN1} + mkdir -p ${DESTDIR}${PREFIX}/bin ${DESTDIR}${MANPREFIX}/man1 + cp -f ${BIN} ${DESTDIR}${PREFIX}/bin + cp -f ${MAN1} ${DESTDIR}${MANPREFIX}/man1 + sed "s/VERSION/${VERSION}/g" < ${MAN1} > ${DESTDIR}${MANPREFIX}/man1/${MAN1} + chmod 755 ${DESTDIR}${PREFIX}/bin/${BIN} + chmod 644 ${DESTDIR}${MANPREFIX}/man1/${MAN1} uninstall: - ${RM} ${DESTDIR}${BIN_DIR}/${BIN} - ${RM} ${DESTDIR}${MAN_DIR}/${MAN1} + rm -f ${DESTDIR}${PREFIX}/bin/${BIN} \ + ${DESTDIR}${MANPREFIX}/man1/${MAN1} clean: - ${RM} ${BIN} ${OBJ} ${DIST}.tar.gz + rm -f ${BIN} ${OBJ} ${DIST}.tar.gz *.core .PHONY: all options clean dist install uninstall run diff --git a/config.h b/config.h @@ -1,11 +1,8 @@ -#ifndef _SFM_CONFIG_H_ -#define _SFM_CONFIG_H_ - /* Used in `xdelay`. */ #define DELAY_MS 350 /* Defines how many lines above the last line scrolling starts. */ -#define SCROLLOFF (YMAX >> 1) +#define SCROLLOFF 4 /* Clumps to 1 if < 1 and to 9 if > 9 */ static uint npanes = 4; @@ -54,6 +51,7 @@ static int colors[] = { [C_STA] = COLOR_BLUE, /* Stats */ }; +/* TODO: slstatus */ /* * Available functions. Inside each function's parentheses is written * which `arg` field has to be assigned a value. @@ -69,7 +67,7 @@ static int colors[] = { * * [TODO]: Go to bottom * * [TODO]: Half scroll up/down * - * - cyclepane(.i): Switch panes. + * - cyclepane({0}): Switch panes. * * - setflag(.i): The name explains it. * * F_SHOWALL: Show hidden files @@ -77,7 +75,7 @@ static int colors[] = { * * F_REDRAW: Redraw current pane * * F_QUIT: Exit program * - * - select(.i): Select an entry: + * - sel(.i): Select an entry: * * 0: Select only one entry * * 1: Select all entries. Currently selected entries get de-selected. * @@ -90,34 +88,34 @@ static int colors[] = { * * Size * * Date * * Reverse (reverses currently selected sorting function) + * + * - prompt({0}): Write something in a prompt and (probably) execute it. */ static struct key keys[] = { /* key func arg */ - { KEY_LEFT, chlevel, {.i = -1} }, - { 'h', chlevel, {.i = -1} }, - { KEY_RIGHT, chlevel, {.i = +1} }, - { 'l', chlevel, {.i = +1} }, - { '\n', chlevel, {.i = +1} }, - { KEY_UP, scrollpane, {.i = -1} }, - { 'k', scrollpane, {.i = -1} }, - { KEY_DOWN, scrollpane, {.i = +1} }, - { 'j', scrollpane, {.i = +1} }, - { 'g', scrollpane, {.i = 0} }, + { KEY_LEFT, chlevel, {.i = -1} }, + { 'h', chlevel, {.i = -1} }, + { KEY_RIGHT, chlevel, {.i = +1} }, + { 'l', chlevel, {.i = +1} }, + { '\n', chlevel, {.i = +1} }, + { KEY_UP, scrollpane, {.i = -1} }, + { 'k', scrollpane, {.i = -1} }, + { KEY_DOWN, scrollpane, {.i = +1} }, + { 'j', scrollpane, {.i = +1} }, + { 'g', scrollpane, {.i = 0} }, //{ 'G', scrollpane, {.i = S_BOTTOM} }, - { '\t', cyclepane, {0} }, - { ' ', select, {.i = 0} }, - { CTRL('a'), select, {.i = 1} }, - { '.', setflag, {.i = F_SHOWALL} }, - { 'i', setflag, {.i = F_INFO} }, - { CTRL('r'), setflag, {.i = F_REDRAW} }, - { 'q', setflag, {.i = F_QUIT} }, - { '~', cd, {.s = "/home/christos"} }, - { CTRL('b'), cd, {.s = "/storage"} }, - { 'p', run, {.s = "PAGER"} }, - { 'e', run, {.s = "EDITOR"} }, - { 'x', run, {.s = "rm -rf"} }, - { 's', sort, {0} }, - { ':', prompt, {0} }, + { '\t', cyclepane, {0} }, + { ' ', sel, {.i = 0} }, + { CTRL('a'), sel, {.i = 1} }, + { '.', setflag, {.i = F_SHOWALL} }, + { 'i', setflag, {.i = F_INFO} }, + { CTRL('r'), setflag, {.i = F_REDRAW} }, + { 'q', setflag, {.i = F_QUIT} }, + { '~', cd, {.s = "/home/christos"} }, + { CTRL('b'), cd, {.s = "/storage"} }, + { 'p', run, {.s = "PAGER"} }, + { 'e', run, {.s = "EDITOR"} }, + { 'x', run, {.s = "rm -rf"} }, + { 's', sort, {0} }, + { ':', prompt, {0} }, }; - -#endif /* _SFM_CONFIG_H_ */ diff --git a/config.mk b/config.mk @@ -1,31 +1,20 @@ # See LICENSE file for copyright and license details. # sfm version -VERSION = 0 +VERSION = 0.1 # paths PREFIX = /usr/local -MAN_DIR = ${PREFIX}/share/man/man1 -BIN_DIR = ${PREFIX}/bin +MANPREFIX = ${PREFIX}/share/man # includes and libs -INCS = -Iinclude -LIBS = -Llib -lcursesw +INCS = -Iinclude +LIBS = -Llib -lncursesw # flags CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L \ - -D_XOPEN_SOURCE=700 -DVERSION=\"${VERSION}\" + -D_XOPEN_SOURCE=700 -DVERSION=\"${VERSION}\" CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = ${LIBS} -# utils -CP = cp -f -RM = rm -f -RM_DIR = rm -rf -MV = mv -MKDIR = mkdir -p -RM_DIR = rm -rf -TAR = tar -cf -GZIP = gzip - # compiler CC = cc diff --git a/sfm.1 b/sfm.1 @@ -6,10 +6,10 @@ .Nd the simple file manager .Sh SYNOPSIS .Nm -.Op Fl ai +.Op Fl aiv .Sh DESCRIPTION .Pp .Nm does stuff. I will write this manual later. .Sh AUTHORS -.An Christos Margiolis Aq Mt christos@christosmarg.xyz +.An Christos Margiolis Aq Mt christos@margiolis.net diff --git a/sfm.c b/sfm.c @@ -4,6 +4,7 @@ #include <sys/wait.h> #include <dirent.h> +#include <err.h> #include <fcntl.h> #include <limits.h> #include <locale.h> @@ -33,9 +34,6 @@ #ifndef ESC #define ESC 27 #endif /* ESC */ -#ifndef DEL -#define DEL 127 -#endif /* DEL */ #ifndef SIGWINCH #define SIGWINCH 28 @@ -49,7 +47,6 @@ #define MIN(x, y) ((x) < (y) ? (x) : (y)) #define MAX(x, y) ((x) > (y) ? (x) : (y)) #define ARRLEN(x) (sizeof(x) / sizeof(x[0])) -#define ISDIGIT(x) ((unsigned int)(x) - '0' <= 9) #define ENTSORT(e, n, f) (qsort((e), (n), sizeof(*(e)), f)) typedef unsigned char uchar; @@ -58,8 +55,7 @@ typedef unsigned long ulong; struct entry { char date[NAME_MAX]; - char statstr[36]; - char sizestr[12]; + char stats[36]; /* XXX: not needed I think */ char *name; off_t sz; mode_t mode; @@ -73,6 +69,8 @@ struct pane { uint nsel; uint nents; int sel; + int cur; + int curscroll; int (*sortfn)(const void *, const void *); }; @@ -121,13 +119,13 @@ enum { C_SPN, /* Selected pane */ C_PTH, /* Path */ C_STA, /* Stats */ - C_LAST, + C_LAST, /* Not used. Has to be last. */ }; static void initcurses(void); static struct entry *entget(const char *); static void entprint(struct pane *); -static int spawn(char *); +static void spawn(char *); static void notify(const char *, ...); static int confirmact(const char *); static int appendbuf(char *, size_t *, const char *); @@ -141,8 +139,8 @@ static void chlevel(const arg *); static void scrollpane(const arg *); static void cyclepane(const arg *); static void setflag(const arg *); -static void _select(struct pane *, int); -static void select(const arg *); +static void _sel(struct pane *, int); +static void sel(const arg *); static void cd(const arg *); static void run(const arg *); static void sort(const arg *); @@ -154,31 +152,28 @@ static char *estrdup(const char *); static void sighandler(int); static void entfree(struct pane *); static void cleanup(void); -static void die(const char *, ...); static const char *msgs[] = { [MSG_EXEC] = "%s (y/N)?", [MSG_SORT] = "'n'ame 's'ize 'd'ate 'r'everse", [MSG_PROMPT] = ":", - [MSG_FAIL] = "action failed", + [MSG_FAIL] = "action failed: %s", }; static char *argv0; /* program name */ static struct pane *pane; /* display */ static int selpane = 0; /* current pane */ -static int cur = 0; /* cursor position */ -static int curscroll = 0; /* cursor scroll */ /* flags */ static uchar f_showall = 0; /* show hidden files */ -static uchar f_redraw = 0; /* redraw screen */ static uchar f_info = 0; /* show info about entries */ static uchar f_noconfirm = 0; /* exec without confirmation */ static uchar f_namesort = 0; /* sort entries by name */ static uchar f_sizesort = 0; /* sort entries by size */ static uchar f_datesort = 0; /* sort entries by date */ static uchar f_revsort = 0; /* reverse current sort function */ -static uchar f_running = 1; /* 0 when sfm should exit */ +static volatile sig_atomic_t f_redraw = 0; /* redraw screen */ +static volatile sig_atomic_t f_running = 1; /* 0 when sfm should exit */ #include "config.h" @@ -225,7 +220,7 @@ initcurses(void) int i, l; if (!initscr()) - die("initscr:"); + errx(1, "initscr"); noecho(); cbreak(); curs_set(0); @@ -233,43 +228,48 @@ initcurses(void) SETTIMEOUT(); set_escdelay(0); - if (has_colors() && can_change_color()) { - start_color(); - use_default_colors(); - l = ARRLEN(colors); - for (i = 1; i < C_LAST; i++) { - /* - * This lets us use any number of elements in `colors`. - * If there's no color for a given entry, it falls back - * to `defaultcolor`. - */ - if (i < l && colors[i]) - (void)init_pair(i, colors[i], COLOR_BLACK); - else - (void)init_pair(i, defaultcolor, COLOR_BLACK); - } + start_color(); + use_default_colors(); + l = ARRLEN(colors); + for (i = 1; i < C_LAST; i++) { + /* + * This lets us use any number of elements in `colors`. + * If there's no color for a given entry, it falls back + * to `defaultcolor`. + */ + if (i < l && colors[i]) + /* FIXME: wrong. */ + (void)init_pair(i, colors[i], -1); + else + (void)init_pair(i, defaultcolor, -1); } - memset(&sa, 0, sizeof(sa)); + (void)memset(&sa, 0, sizeof(sa)); + (void)sigemptyset(&sa.sa_mask); sa.sa_handler = sighandler; sa.sa_flags = SA_RESTART; - sigemptyset(&sa.sa_mask); - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGWINCH, &sa, NULL); + if (sigaction(SIGINT, &sa, NULL) < 0) + err(1, "sigaction: SIGINT"); + if (sigaction(SIGTERM, &sa, NULL) < 0) + err(1, "sigaction: SIGTERM"); + if (sigaction(SIGUSR1, &sa, NULL) < 0) + err(1, "sigaction: SIGUSR1"); + if (sigaction(SIGWINCH, &sa, NULL) < 0) + err(1, "sigaction: SIGWINCH"); } static struct entry * entget(const char *path) { struct entry *ents, *e; - struct stat st; struct dirent *dent; + struct stat st; DIR *dir; int i = 0; char type; if ((dir = opendir(path)) == NULL) - die("opendir: %s:", path); + err(1, "opendir: %s:", path); ents = emalloc(sizeof(struct entry)); @@ -289,7 +289,6 @@ entget(const char *path) e->sz = st.st_size; e->mode = st.st_mode; strftime(e->date, sizeof(e->date), datefmt, localtime(&st.st_ctime)); - (void)strncpy(e->sizestr, fmtsize(e->sz), sizeof(e->sizestr)); /* XXX: resets on every redraw, keep track somehow */ e->selected = 0; @@ -322,7 +321,7 @@ entget(const char *path) break; } - snprintf(e->statstr, sizeof(e->statstr), + snprintf(e->stats, sizeof(e->stats), "%c%c%c%c%c%c%c%c%c%c %s %s", type, e->mode & S_IRUSR ? 'r' : '-', @@ -334,7 +333,7 @@ entget(const char *path) e->mode & S_IROTH ? 'r' : '-', e->mode & S_IWOTH ? 'w' : '-', e->mode & S_IXOTH ? 'x' : '-', - e->sizestr, + fmtsize(e->sz), e->date); i++; @@ -373,28 +372,29 @@ entprint(struct pane *p) namprint(p->curdir); attroff(A_BOLD | COLOR_PAIR(C_PTH)); - if ((n = MIN(YMAX - 4, p->nents - curscroll)) <= 0) + if ((n = MIN(YMAX - 4, p->nents - p->curscroll)) <= 0) return; for (i = 0; i < n; i++) { - e = &p->ents[i + curscroll]; + /* FIXME: segfault when going back if curscroll is too big */ + e = &p->ents[i + p->curscroll]; ind = ' '; attrs = 0; color = 0; move(i + 2, 0); - if (i == cur) + if (i == p->cur) attrs |= A_REVERSE; if (f_info) { attron(COLOR_PAIR(C_INF)); printw("%s %c%c%c %7s ", e->date, - '0' + ((e->mode >> 6) & 7), - '0' + ((e->mode >> 3) & 7), - '0' + (e->mode & 7), - e->sizestr); + ((e->mode >> 6) & 7) + '0', + ((e->mode >> 3) & 7) + '0', + (e->mode & 7) + '0', + fmtsize(e->sz)); attroff(COLOR_PAIR(C_INF)); } @@ -449,33 +449,31 @@ entprint(struct pane *p) } attron(COLOR_PAIR(C_STA)); mvprintw(YMAX - 1, 0, "%ld/%ld %s", - p->sel + 1, p->nents, p->ents[p->sel].statstr); + p->sel + 1, p->nents, p->ents[p->sel].stats); attroff(COLOR_PAIR(C_STA)); } -static int +/* FIXME: weird stuff with select all */ +static void spawn(char *cmd) { char *args[] = {getenv("SHELL"), "-c", cmd, NULL}; - pid_t pid; - int status; - switch (pid = fork()) { + switch (fork()) { case -1: - notify(msgs[MSG_FAIL]); + notify(msgs[MSG_FAIL], "fork"); xdelay(DELAY_MS << 2); - return 1; + break; case 0: (void)execvp(*args, args); - _exit(EXIT_SUCCESS); + _exit(0); break; default: - endwin(); - while (wait(&status) != pid) - ; + (void)endwin(); + if (wait(NULL) < 0) + err(1, "wait"); break; } - return 0; } static void @@ -503,6 +501,7 @@ confirmact(const char *str) notify(msgs[MSG_EXEC], str); c = getch(); SETTIMEOUT(); + return (c == 'y'); } @@ -537,15 +536,16 @@ escape(const char *str) for (; *str; str++) { switch (*str) { case ' ': /* FALLTHROUGH */ - case '\'': /* FALLTHROUGH */ - case '(': /* FALLTHROUGH */ - case ')': /* FALLTHROUGH */ + case '\'': + case '(': + case ')': buf = erealloc(buf, ++sz + 1); buf[i++] = '\\'; } buf[i++] = *str; } buf[i] = '\0'; + return buf; } @@ -557,7 +557,7 @@ fmtsize(size_t sz) for (; sz > 1024; i++) sz >>= 10; - snprintf(buf, sizeof(buf), "%ld%c", sz, "BKMGTPEZY"[i]); + (void)snprintf(buf, sizeof(buf), "%ld%c", sz, "BKMGTPEZY"[i]); return buf; } @@ -567,12 +567,8 @@ namprint(char *str) { char *s; - for (s = str; *s != '\0'; s++) { - if ((s - str) > XMAX - 1) - break; + for (s = str; *s != '\0' && (s - str) < XMAX; s++) addch(*s); - } - return; } static char * @@ -584,18 +580,21 @@ promptread(const char *msg) notify(msg); echo(); curs_set(1); + CLRTIMEOUT(); while ((c = getch()) != '\n') { switch (c) { case KEY_BACKSPACE: /* FALLTHROUGH */ - case KEY_DC: /* FALLTHROUGH */ - case '\b': /* FALLTHROUGH */ + case KEY_DC: + case '\b': if (len > 0) len--; break; case ESC: str = NULL; goto exit; + case ERR: + break; default: buf[len++] = c; } @@ -606,6 +605,7 @@ promptread(const char *msg) exit: curs_set(0); noecho(); + SETTIMEOUT(); return str; } @@ -617,7 +617,7 @@ selclump(struct pane *p) p->sel = 0; else if (p->sel > p->nents - 1) p->sel = p->nents - 1; - cur = p->sel; + p->cur = p->sel; } /* TODO: use nanosleep(2) */ @@ -669,12 +669,12 @@ scrollpane(const arg *arg) p->sel = 0; selclump(p); if (p->sel > YMAX - 4 - SCROLLOFF) { - cur = YMAX - 4 - SCROLLOFF; - if (cur + curscroll + arg->i < p->nents) - curscroll += arg->i; + p->cur = YMAX - 4 - SCROLLOFF; + if (p->cur + p->curscroll + arg->i < p->nents) + p->curscroll += arg->i; } else { - cur = p->sel; - curscroll = 0; + p->cur = p->sel; + p->curscroll = 0; } } @@ -701,7 +701,7 @@ setflag(const arg *arg) } static void -_select(struct pane *p, int i) +_sel(struct pane *p, int i) { p->ents[i].selected ^= 1; if (p->ents[i].selected) @@ -711,17 +711,17 @@ _select(struct pane *p, int i) } static void -select(const arg *arg) +sel(const arg *arg) { struct pane *p; int i; p = &pane[selpane]; if (arg->i == 0) - _select(p, p->sel); + _sel(p, p->sel); else for (i = 0; i < p->nents; i++) - _select(p, i); + _sel(p, i); } static void @@ -748,9 +748,9 @@ run(const arg *arg) */ if ((prog = getenv(arg->s)) == NULL) prog = (char *)arg->s; /* Remove `const`ness. */ - p = &pane[selpane]; sz = strlen(prog); (void)strncpy(buf, prog, ++sz); + p = &pane[selpane]; if (p->nsel > 0) { for (i = 0; i < p->nents; i++) @@ -833,8 +833,8 @@ prompt(const arg *arg) static void echdir(const char *path) { - if (chdir(path) == -1) { - notify(msgs[MSG_FAIL]); + if (chdir(path) < 0) { + notify(msgs[MSG_FAIL], "chdir"); xdelay(DELAY_MS << 2); } } @@ -845,7 +845,8 @@ emalloc(size_t nb) void *p; if ((p = malloc(nb)) == NULL) - die("emalloc:"); + err(1, "malloc"); + return p; } @@ -853,7 +854,8 @@ static void * erealloc(void *p, size_t nb) { if ((p = realloc(p, nb)) == NULL) - die("realloc:"); + err(1, "realloc"); + return p; } @@ -863,7 +865,7 @@ estrdup(const char *s) char *p; if ((p = strdup(s)) == NULL) - die("strdup:"); + err(1, "strdup"); return p; } @@ -871,9 +873,10 @@ static void sighandler(int sig) { switch (sig) { + case SIGINT: /* FALLTHROUGH */ case SIGTERM: - cleanup(); - _exit(128 + sig); + case SIGUSR1: + f_running = 0; case SIGWINCH: f_redraw = 1; break; @@ -884,7 +887,7 @@ static void entfree(struct pane *p) { int i= 0; - + for (; i < p->nents; i++) free(p->ents[i].name); free(p->ents); @@ -903,26 +906,6 @@ cleanup(void) endwin(); } -static void -die(const char *fmt, ...) -{ - va_list args; - - (void)fprintf(stderr, "%s: ", argv0); - va_start(args, fmt); - (void)vfprintf(stderr, fmt, args); - va_end(args); - - if (fmt[0] && fmt[strlen(fmt)-1] == ':') { - fputc(' ', stderr); - perror(NULL); - } else - fputc('\n', stderr); - - cleanup(); - exit(EXIT_FAILURE); -} - int main(int argc, char *argv[]) { @@ -932,11 +915,11 @@ main(int argc, char *argv[]) argv0 = *argv; if (!setlocale(LC_ALL, "")) - die("setlocale:"); + errx(1, "setlocale"); if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) - die("isatty:"); + err(1, "isatty"); - while ((ch = getopt(argc, argv, "ai")) != -1) { + while ((ch = getopt(argc, argv, "aiv")) != -1) { switch (ch) { case 'a': f_showall = 1; @@ -944,10 +927,13 @@ main(int argc, char *argv[]) case 'i': f_info = 1; break; + case 'v': + fprintf(stderr, "%s-"VERSION"\n", argv0); + exit(1); case '?': /* FALLTHROUGH */ default: - (void)fprintf(stderr, "usage: %s [-ai]\n", argv0); - exit(EXIT_FAILURE); + fprintf(stderr, "usage: %s [-aiv]\n", argv0); + exit(1); } } argc -= optind; @@ -964,7 +950,9 @@ main(int argc, char *argv[]) for (i = 0; i < npanes; i++) { pane[i].ents = NULL; pane[i].curdir = NULL; - pane[i].sel = pane[i].nsel = pane[i].nents = 0; + pane[i].nents = 0; + pane[i].sel = pane[i].nsel = 0; + pane[i].cur = pane[i].curscroll = 0; pane[i].sortfn = namecmp; } /* TODO: add [dir] */ @@ -976,10 +964,10 @@ main(int argc, char *argv[]) if (f_redraw) { /* FIXME: getcwd(3) is not suitable anymore... */ if ((p->curdir = getcwd(cwd, sizeof(cwd))) == NULL) - die("getcwd:"); + err(1, "getcwd"); entfree(p); if ((p->ents = entget(p->curdir)) == NULL) - die("entget: %s:", p->curdir); + errx(1, "entget: %s", p->curdir); selclump(p); f_redraw = 0; refresh(); @@ -996,7 +984,6 @@ main(int argc, char *argv[]) f_redraw = 1; } } - refresh(); } cleanup();