diff options
Diffstat (limited to 'sfm-0.4/sfm.c')
| -rw-r--r-- | sfm-0.4/sfm.c | 2033 |
1 files changed, 0 insertions, 2033 deletions
diff --git a/sfm-0.4/sfm.c b/sfm-0.4/sfm.c deleted file mode 100644 index 3a69586..0000000 --- a/sfm-0.4/sfm.c +++ /dev/null @@ -1,2033 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -#if defined(__linux__) -#define _GNU_SOURCE -#elif defined(__APPLE__) -#define _DARWIN_C_SOURCE -#elif defined(__FreeBSD__) -#define __BSD_VISIBLE 1 -#endif -#include <sys/types.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/wait.h> -#if defined(__linux__) -#include <sys/inotify.h> -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ - defined(__APPLE__) -#include <sys/event.h> -#endif - -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <grp.h> -#include <libgen.h> -#include <pthread.h> -#include <pwd.h> -#include <signal.h> -#include <stdarg.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> - -#include "termbox.h" -#include "util.h" - -/* macros */ -#define MAX_P 4096 -#define MAX_N 255 -#define MAX_USRI 32 -#define MAX_EXT 4 -#define MAX_STATUS 255 -#define MAX_LINE 4096 -#define MAX_USRN 32 -#define MAX_GRPN 32 -#define MAX_DTF 32 -#define CURSOR(x) (x)->direntr[(x)->hdir - 1] - -/* typedef */ -typedef struct { - char name[MAX_N]; - gid_t group; - mode_t mode; - off_t size; - time_t dt; - uid_t user; -} Entry; - -typedef struct { - uint16_t fg; - uint16_t bg; -} Cpair; - -typedef struct { - int pane_id; - char dirn[MAX_P]; // dir name cwd - char *filter; - Entry *direntr; // dir entries - int dirc; // dir entries sum - int hdir; // highlighted dir - int x_srt; - int x_end; - int firstrow; - int parent_firstrow; - int parent_row; // FIX - Cpair dircol; - int inotify_wd; - int event_fd; -} Pane; - -typedef struct { - const char **ext; - size_t exlen; - const void *v; - size_t vlen; -} Rule; - -typedef union { - uint16_t key; /* one of the TB_KEY_* constants */ - uint32_t ch; /* unicode character */ -} Evkey; - -typedef union { - int i; - const void *v; -} Arg; - -typedef struct { - const Evkey evkey; - void (*func)(const Arg *); - const Arg arg; -} Key; - -/* function declarations */ -static void print_tb(const char *, int, int, uint16_t, uint16_t); -static void printf_tb(int, int, Cpair, const char *, ...); -static void print_status(Cpair, const char *, ...); -static void print_xstatus(char, int); -static void print_error(char *); -static void print_prompt(char *); -static void print_info(Pane *, char *); -static void print_row(Pane *, size_t, Cpair); -static void clear(int, int, int, uint16_t); -static void clear_status(void); -static void clear_pane(Pane *); -static void add_hi(Pane *, size_t); -static void rm_hi(Pane *, size_t); -static int check_dir(char *); -static int sort_name(const void *const, const void *const); -static void get_dirp(char *); -static char *get_ext(char *); -static int get_fdt(char *, time_t); -static char *get_fgrp(gid_t); -static char *get_fperm(mode_t); -static char *get_fsize(off_t); -static char *get_fullpath(char *, char *); -static char *get_fusr(uid_t); -static void get_dirsize(char *, off_t *); -static void get_hicol(Cpair *, mode_t); -static void delent(const Arg *arg); -static void calcdir(const Arg *arg); -static void crnd(const Arg *arg); -static void crnf(const Arg *arg); -static void mv_ver(const Arg *arg); -static void mvbk(const Arg *arg); -static void mvbtm(const Arg *arg); -static void mvfwd(const Arg *arg); -static void mvtop(const Arg *arg); -static void bkmrk(const Arg *arg); -static int get_usrinput(char *, size_t, const char *, ...); -static int frules(char *); -static int spawn(const void *, size_t, const void *, size_t, char *, int); -static int opnf(char *); -static int fsev_init(void); -static int addwatch(Pane *); -static int read_events(void); -static void rmwatch(Pane *); -static void fsev_shdn(void); -static void toggle_df(const Arg *arg); -static void start_filter(const Arg *arg); -static void start_vmode(const Arg *arg); -static void exit_vmode(const Arg *arg); -static void start_change(const Arg *arg); -static void exit_change(const Arg *arg); -static void selup(const Arg *arg); -static void seldwn(const Arg *arg); -static void selall(const Arg *arg); -static void selref(void); -static void selynk(const Arg *arg); -static void selcalc(void); -static void paste(const Arg *arg); -static void selmv(const Arg *arg); -static void seldel(const Arg *arg); -static void init_files(void); -static void free_files(void); -static void yank(const Arg *arg); -static void rname(const Arg *arg); -static void chngo(const Arg *arg); -static void chngm(const Arg *arg); -static void chngf(const Arg *arg); -static void dupl(const Arg *arg); -static void switch_pane(const Arg *arg); -static void quit(const Arg *arg); -static void grabkeys(struct tb_event *, Key *, size_t); -static void *read_th(void *arg); -static void start_ev(void); -static void refresh_pane(Pane *); -static void set_direntr(Pane *, struct dirent *, DIR *, char *); -static int listdir(Pane *); -static void t_resize(void); -static void get_shell(void); -static void opnsh(const Arg *arg); -static void set_panes(void); -static void draw_frame(void); -static void refresh(const Arg *arg); -static void start(void); - -/* global variables */ -static pthread_t fsev_thread; -static Pane panes[2]; -static Pane *cpane; -static int pane_idx; -static char *editor[2]; -static char fed[] = "vi"; -static char *shell[2]; -static char sh[] = "/bin/sh"; -static int theight, twidth, hwidth, scrheight; -static int *sel_indexes; -static size_t sel_len = 0; -static char **sel_files; -static int cont_vmode = 0; -static int cont_change = 0; -static pid_t fork_pid = 0, main_pid; -#if defined(_SYS_INOTIFY_H) -#define READEVSZ 16 -static int inotify_fd; -#elif defined(_SYS_EVENT_H_) -#define READEVSZ 0 -static int kq; -struct kevent evlist[2]; /* events we want to monitor */ -struct kevent chlist[2]; /* events that were triggered */ -static struct timespec gtimeout; -#endif -#if defined(__linux__) || defined(__FreeBSD__) -#define OFF_T "%ld" -#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) -#define OFF_T "%lld" -#endif -enum { Left, Right }; /* panes */ -enum { Wait, DontWait }; /* spawn forks */ - -/* configuration, allows nested code to access above variables */ -#include "config.h" - -/* function implementations */ -static void -print_tb(const char *str, int x, int y, uint16_t fg, uint16_t bg) -{ - while (*str != '\0') { - uint32_t uni = 0; - str += tb_utf8_char_to_unicode(&uni, str); - tb_change_cell(x, y, uni, fg, bg); - x++; - } -} - -static void -printf_tb(int x, int y, Cpair col, const char *fmt, ...) -{ - char buf[MAX_LINE]; - va_list vl; - va_start(vl, fmt); - (void)vsnprintf(buf, MAX_LINE, fmt, vl); - va_end(vl); - print_tb(buf, x, y, col.fg, col.bg); -} - -static void -print_status(Cpair col, const char *fmt, ...) -{ - char buf[MAX_STATUS]; - va_list vl; - va_start(vl, fmt); - (void)vsnprintf(buf, MAX_STATUS, fmt, vl); - va_end(vl); - clear_status(); - print_tb(buf, 1, theight - 1, col.fg, col.bg); -} - -static void -print_xstatus(char c, int x) -{ - uint32_t uni = 0; - (void)tb_utf8_char_to_unicode(&uni, &c); - tb_change_cell(x, theight - 1, uni, cstatus.fg, cstatus.bg); -} - -static void -print_error(char *errmsg) -{ - print_status(cerr, errmsg); -} - -static void -print_prompt(char *prompt) -{ - print_status(cprompt, prompt); -} - -static void -print_info(Pane *pane, char *dirsize) -{ - char *sz, *ur, *gr, *dt, *prm; - - dt = ecalloc(MAX_DTF, sizeof(char)); - - prm = get_fperm(CURSOR(pane).mode); - ur = get_fusr(CURSOR(pane).user); - gr = get_fgrp(CURSOR(pane).group); - - if (get_fdt(dt, CURSOR(pane).dt) < 0) - *dt = '\0'; - - if (S_ISREG(CURSOR(pane).mode)) { - sz = get_fsize(CURSOR(pane).size); - } else { - if (dirsize == NULL) { - sz = ecalloc(1, sizeof(char)); - *sz = '\0'; - } else { - sz = dirsize; - } - } - - print_status(cstatus, "%02d/%02d %s %s:%s %s %s", pane->hdir, - pane->dirc, prm, ur, gr, dt, sz); - - free(prm); - free(ur); - free(gr); - free(dt); - free(sz); -} - -static void -print_row(Pane *pane, size_t entpos, Cpair col) -{ - int x, y; - char *full_str, *rez_pth; - char lnk_full[MAX_N]; - - full_str = basename(pane->direntr[entpos].name); - x = pane->x_srt; - y = entpos - pane->firstrow + 1; - - if (S_ISLNK(pane->direntr[entpos].mode) != 0) { - rez_pth = ecalloc(MAX_P, sizeof(char)); - if (realpath(pane->direntr[entpos].name, rez_pth) != NULL) { - snprintf( - lnk_full, MAX_N, "%s -> %s", full_str, rez_pth); - full_str = lnk_full; - } - free(rez_pth); - } - - printf_tb(x, y, col, "%*.*s", ~hwidth, hwidth, full_str); -} - -static void -clear(int sx, int ex, int y, uint16_t bg) -{ - /* clear line from to */ - /* x = line number vertical */ - /* y = column number horizontal */ - int i; - for (i = sx; i < ex; i++) { - tb_change_cell(i, y, 0x0000, TB_DEFAULT, bg); - } -} - -static void -clear_status(void) -{ - clear(1, twidth - 1, theight - 1, cstatus.bg); -} - -static void -clear_pane(Pane *pane) -{ - int i, y; - y = 0, i = 0; - - while (i < scrheight) { - clear(pane->x_srt, pane->x_end, y, TB_DEFAULT); - i++; - y++; - } - - /* draw top line */ - for (y = pane->x_srt; y < pane->x_end; ++y) { - tb_change_cell(y, 0, u_hl, cframe.fg, cframe.bg); - } -} - -static void -add_hi(Pane *pane, size_t entpos) -{ - Cpair col; - get_hicol(&col, pane->direntr[entpos].mode); - col.fg |= TB_REVERSE | TB_BOLD; - col.bg |= TB_REVERSE; - print_row(pane, entpos, col); -} - -static void -rm_hi(Pane *pane, size_t entpos) -{ - Cpair col; - get_hicol(&col, pane->direntr[entpos].mode); - print_row(pane, entpos, col); -} - -static int -check_dir(char *path) -{ - DIR *dir; - dir = opendir(path); - - if (dir == NULL) { - if (errno == ENOTDIR) { - return 1; - } else { - return -1; - } - } - - if (closedir(dir) < 0) - return -1; - - return 0; -} - -static int -sort_name(const void *const A, const void *const B) -{ - int result; - mode_t data1 = (*(Entry *)A).mode; - mode_t data2 = (*(Entry *)B).mode; - - if (data1 < data2) { - return -1; - } else if (data1 == data2) { - result = strncmp((*(Entry *)A).name, (*(Entry *)B).name, MAX_N); - return result; - } else { - return 1; - } -} - -static void -get_dirp(char *cdir) -{ - int counter, len, i; - - counter = 0; - len = strnlen(cdir, MAX_P); - if (len == 1) - return; - - for (i = len - 1; i > 1; i--) { - if (cdir[i] == '/') - break; - else - counter++; - } - - cdir[len - counter - 1] = '\0'; -} - -static char * -get_ext(char *str) -{ - char *ext; - char dot; - size_t counter, len, i; - - dot = '.'; - counter = 0; - len = strnlen(str, MAX_N); - - for (i = len - 1; i > 0; i--) { - if (str[i] == dot) { - break; - } else { - counter++; - } - } - - ext = ecalloc(MAX_EXT + 1, sizeof(char)); - strncpy(ext, &str[len - counter], MAX_EXT); - ext[MAX_EXT] = '\0'; - return ext; -} - -static int -get_fdt(char *result, time_t status) -{ - struct tm lt; - localtime_r(&status, <); - return strftime(result, MAX_DTF, dtfmt, <); -} - -static char * -get_fgrp(gid_t status) -{ - char *result; - struct group *gr; - - result = ecalloc(MAX_GRPN, sizeof(char)); - gr = getgrgid(status); - if (gr == NULL) - (void)snprintf(result, MAX_GRPN, "%u", status); - else - strncpy(result, gr->gr_name, MAX_GRPN); - - result[MAX_GRPN - 1] = '\0'; - return result; -} - -static char * -get_fperm(mode_t mode) -{ - char *buf; - size_t i; - - const char chars[] = "rwxrwxrwx"; - buf = ecalloc(11, sizeof(char)); - - if (S_ISDIR(mode)) - buf[0] = 'd'; - else if (S_ISREG(mode)) - buf[0] = '-'; - else if (S_ISLNK(mode)) - buf[0] = 'l'; - else if (S_ISBLK(mode)) - buf[0] = 'b'; - else if (S_ISCHR(mode)) - buf[0] = 'c'; - else if (S_ISFIFO(mode)) - buf[0] = 'p'; - else if (S_ISSOCK(mode)) - buf[0] = 's'; - else - buf[0] = '?'; - - for (i = 1; i < 10; i++) { - buf[i] = (mode & (1 << (9 - i))) ? chars[i - 1] : '-'; - } - buf[10] = '\0'; - - return buf; -} - -static char * -get_fsize(off_t size) -{ - char *result; /* need to be freed */ - char unit; - int result_len; - int counter; - - counter = 0; - result_len = 6; /* 9999X/0 */ - result = ecalloc(result_len, sizeof(char)); - - while (size >= 1000) { - size /= 1024; - ++counter; - } - - switch (counter) { - case 0: - unit = 'B'; - break; - case 1: - unit = 'K'; - break; - case 2: - unit = 'M'; - break; - case 3: - unit = 'G'; - break; - case 4: - unit = 'T'; - break; - default: - unit = '?'; - } - - if (snprintf(result, result_len, OFF_T "%c", size, unit) < 0) - strncat(result, "???", result_len); - - return result; -} - -static char * -get_fullpath(char *first, char *second) -{ - char *full_path; - - full_path = ecalloc(MAX_P, sizeof(char)); - - if (strncmp(first, "/", MAX_P) == 0) - (void)snprintf(full_path, MAX_P, "/%s", second); - else - (void)snprintf(full_path, MAX_P, "%s/%s", first, second); - - return full_path; -} - -static char * -get_fusr(uid_t status) -{ - char *result; - struct passwd *pw; - - result = ecalloc(MAX_USRN, sizeof(char)); - pw = getpwuid(status); - if (pw == NULL) - (void)snprintf(result, MAX_USRN, "%u", status); - else - strncpy(result, pw->pw_name, MAX_USRN); - - result[MAX_USRN - 1] = '\0'; - return result; -} - -static void -get_dirsize(char *fullpath, off_t *fullsize) -{ - DIR *dir; - char *ent_full; - mode_t mode; - struct dirent *entry; - struct stat status; - - dir = opendir(fullpath); - if (dir == NULL) { - return; - } - - while ((entry = readdir(dir)) != 0) { - if ((strncmp(entry->d_name, ".", 2) == 0 || - strncmp(entry->d_name, "..", 3) == 0)) - continue; - - ent_full = get_fullpath(fullpath, entry->d_name); - if (lstat(ent_full, &status) == 0) { - mode = status.st_mode; - if (S_ISDIR(mode)) { - get_dirsize(ent_full, fullsize); - free(ent_full); - } else { - *fullsize += status.st_size; - free(ent_full); - } - } - } - - closedir(dir); - clear_status(); -} - -static void -get_hicol(Cpair *col, mode_t mode) -{ - switch (mode & S_IFMT) { - case S_IFREG: - *col = cfile; - if ((S_IXUSR | S_IXGRP | S_IXOTH) & mode) - *col = cexec; - break; - case S_IFDIR: - *col = cdir; - break; - case S_IFLNK: - *col = clnk; - break; - case S_IFBLK: - *col = cblk; - break; - case S_IFCHR: - *col = cchr; - break; - case S_IFIFO: - *col = cifo; - break; - case S_IFSOCK: - *col = csock; - break; - default: - *col = cother; - break; - } -} - -static void -delent(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - char *inp_conf; - - inp_conf = ecalloc(delconf_len, sizeof(char)); - if ((get_usrinput(inp_conf, delconf_len, "delete files(s) (%s) ?", - delconf) < 0) || - (strncmp(inp_conf, delconf, delconf_len) != 0)) { - free(inp_conf); - return; /* canceled by user or wrong inp_conf */ - } - free(inp_conf); - - char *tmp[1]; - tmp[0] = CURSOR(cpane).name; - if (spawn(rm_cmd, rm_cmd_len, tmp, 1, NULL, DontWait) < 0) { - print_error(strerror(errno)); - return; - } -} - -static void -calcdir(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - if (!S_ISDIR(CURSOR(cpane).mode)) - return; - - off_t *fullsize; - char *csize; - - fullsize = ecalloc(1, sizeof(off_t)); - get_dirsize(CURSOR(cpane).name, fullsize); - csize = get_fsize(*fullsize); - - CURSOR(cpane).size = *fullsize; - print_info(cpane, csize); - free(fullsize); -} - -static void -crnd(const Arg *arg) -{ - char *user_input, *path; - - user_input = ecalloc(MAX_USRI, sizeof(char)); - if (get_usrinput(user_input, MAX_USRI, "new dir") < 0) { - free(user_input); - return; - } - - path = ecalloc(MAX_P, sizeof(char)); - if (snprintf(path, MAX_P, "%s/%s", cpane->dirn, user_input) < 0) { - free(user_input); - free(path); - return; - } - - PERROR(mkdir(path, ndir_perm) < 0); - - free(user_input); - free(path); -} - -static void -crnf(const Arg *arg) -{ - char *user_input, *path; - int rf; - - user_input = ecalloc(MAX_USRI, sizeof(char)); - if (get_usrinput(user_input, MAX_USRI, "new file") < 0) { - free(user_input); - return; - } - - path = ecalloc(MAX_P, sizeof(char)); - if (snprintf(path, MAX_P, "%s/%s", cpane->dirn, user_input) < 0) { - free(user_input); - free(path); - return; - } - - rf = open(path, O_CREAT | O_EXCL, nf_perm); - - if (rf < 0) - print_error(strerror(errno)); - else if (close(rf) < 0) - print_error(strerror(errno)); - - free(user_input); - free(path); -} -static void -mv_ver(const Arg *arg) -{ - - if (cpane->dirc < 1) - return; - if (cpane->hdir - arg->i < 1) /* first line */ - return; - - if (cpane->hdir - arg->i > cpane->dirc) /* last line */ - return; - - if (cpane->firstrow > 0 && arg->i > 0 && - cpane->hdir <= (cpane->firstrow + arg->i)) { /* scroll up */ - cpane->firstrow = cpane->firstrow - arg->i; - rm_hi(cpane, cpane->hdir - 1); - cpane->hdir = cpane->hdir - arg->i; - refresh_pane(cpane); - add_hi(cpane, cpane->hdir - 1); - return; - } - - if (cpane->hdir - cpane->firstrow >= scrheight + arg->i && - arg->i < 0) { /* scroll down */ - cpane->firstrow = cpane->firstrow - arg->i; - rm_hi(cpane, cpane->hdir - 1); - cpane->hdir = cpane->hdir - arg->i; - refresh_pane(cpane); - add_hi(cpane, cpane->hdir - 1); - return; - } - - rm_hi(cpane, cpane->hdir - 1); - cpane->hdir = cpane->hdir - arg->i; - add_hi(cpane, cpane->hdir - 1); - print_info(cpane, NULL); -} - -static void -mvbk(const Arg *arg) -{ - if (cpane->dirn[0] == '/' && cpane->dirn[1] == '\0') { /* cwd = / */ - return; - } - - get_dirp(cpane->dirn); - if (check_dir(cpane->dirn) < 0) { - print_error(strerror(errno)); - return; - } - - cpane->firstrow = cpane->parent_firstrow; - cpane->hdir = cpane->parent_row; - PERROR(listdir(cpane) < 0); - cpane->parent_firstrow = 0; - cpane->parent_row = 1; -} - -static void -mvbtm(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - if (cpane->dirc > scrheight) { - rm_hi(cpane, cpane->hdir - 1); - cpane->hdir = cpane->dirc; - cpane->firstrow = cpane->dirc - scrheight + 1; - refresh_pane(cpane); - add_hi(cpane, cpane->hdir - 1); - } else { - rm_hi(cpane, cpane->hdir - 1); - cpane->hdir = cpane->dirc; - add_hi(cpane, cpane->hdir - 1); - } - print_info(cpane, NULL); -} - -static void -mvfwd(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - int s; - - switch (check_dir(CURSOR(cpane).name)) { - case 0: - strncpy(cpane->dirn, CURSOR(cpane).name, MAX_P); - cpane->parent_row = cpane->hdir; - cpane->parent_firstrow = cpane->firstrow; - cpane->hdir = 1; - cpane->firstrow = 0; - PERROR(listdir(cpane) < 0); - break; - case 1: /* not a directory open file */ - tb_shutdown(); - s = opnf(CURSOR(cpane).name); - if (tb_init() != 0) - die("tb_init"); - t_resize(); - if (s < 0) - print_error("process failed non-zero exit"); - break; - case -1: /* failed to open directory */ - print_error(strerror(errno)); - } -} - -static void -mvtop(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - if (cpane->dirc > scrheight) { - rm_hi(cpane, cpane->hdir - 1); - cpane->hdir = 1; - cpane->firstrow = 0; - refresh_pane(cpane); - add_hi(cpane, cpane->hdir - 1); - } else { - rm_hi(cpane, cpane->hdir - 1); - cpane->hdir = 1; - add_hi(cpane, cpane->hdir - 1); - print_info(cpane, NULL); - } -} - -static void -bkmrk(const Arg *arg) -{ - if (check_dir((char *)arg->v) != 0) { - print_error(strerror(errno)); - return; - } - - strncpy(cpane->dirn, (char *)arg->v, MAX_P); - cpane->firstrow = 0; - cpane->parent_row = 1; - cpane->hdir = 1; - PERROR(listdir(cpane) < 0); -} - -static int -get_usrinput(char *result, size_t max_chars, const char *fmt, ...) -{ - char msg[MAX_N]; - size_t i, cpos, startat; - struct tb_event fev; - va_list vl; - - i = 0; - cpos = 1; - - va_start(vl, fmt); - startat = vsnprintf(msg, MAX_N, fmt, vl) + 1; - va_end(vl); - - clear_status(); - print_tb(msg, 1, theight - 1, cprompt.fg, cprompt.bg); - tb_set_cursor(startat + 1, theight - 1); - tb_present(); - - while (tb_poll_event(&fev) != 0) { - switch (fev.type) { - case TB_EVENT_KEY: - if (fev.key == TB_KEY_ESC) { - tb_set_cursor(-1, -1); - clear_status(); - return -1; - } - - if (fev.key == TB_KEY_BACKSPACE || - fev.key == TB_KEY_BACKSPACE2) { - if (BETWEEN(cpos, 2, max_chars)) { - result[i - 1] = '\0'; - cpos--; - i--; - print_xstatus(' ', startat + cpos); - tb_set_cursor( - startat + cpos, theight - 1); - } - - } else if (fev.key == TB_KEY_ENTER) { - tb_set_cursor(-1, -1); - result[cpos - 1] = '\0'; - return 0; - - } else if (fev.key) { /* disable other TB_KEY_* */ - break; - - } else { - if (cpos < max_chars) { - print_xstatus( - (char)fev.ch, (startat + cpos)); - result[i] = (char)fev.ch; - tb_set_cursor((startat + cpos + 1), - theight - 1); - cpos++; - i++; - } - } - - tb_present(); - break; - - case TB_EVENT_RESIZE: - t_resize(); - clear_status(); - print_tb(msg, 1, theight - 1, cprompt.fg, cprompt.bg); - print_tb(result, startat + 1, theight - 1, cstatus.fg, - cstatus.bg); - tb_present(); - break; - - default: - return -1; - } - } - - return -1; -} - -static int -frules(char *ex) -{ - size_t c, d; - - for (c = 0; c < LEN(rules); c++) - for (d = 0; d < rules[c].exlen; d++) - if (strncmp(rules[c].ext[d], ex, MAX_EXT) == 0) - return c; - return -1; -} - -static int -spawn(const void *com_argv, size_t com_argc, const void *f_argv, size_t f_argc, - char *fn, int waiting) -{ - int ws; - size_t argc; - pid_t r; - - argc = com_argc + f_argc + 2; - char *argv[argc]; - - memcpy(argv, com_argv, com_argc * sizeof(char *)); /* command */ - memcpy(&argv[com_argc], f_argv, f_argc * sizeof(char *)); /* files */ - - argv[argc - 2] = fn; - argv[argc - 1] = NULL; - - fork_pid = fork(); - switch (fork_pid) { - case -1: - return -1; - case 0: - execvp(argv[0], argv); - exit(EXIT_SUCCESS); - default: - if (waiting == Wait) { - while ((r = waitpid(fork_pid, &ws, 0)) == -1 && - errno == EINTR) - continue; - if (r == -1) - return -1; - if ((WIFEXITED(ws) != 0) && (WEXITSTATUS(ws) != 0)) - return -1; - } - } - fork_pid = 0; /* enable th_handler() */ - return 0; -} - -static int -opnf(char *fn) -{ - char *ex; - int c; - - ex = get_ext(fn); - c = frules(ex); - free(ex); - - if (c < 0) /* extension not found open in editor */ - return spawn(editor, 1, NULL, 0, fn, Wait); - else - return spawn( - (char **)rules[c].v, rules[c].vlen, NULL, 0, fn, Wait); -} - -static void -opnsh(const Arg *arg) -{ - int s; - - tb_shutdown(); - chdir(cpane->dirn); - s = spawn(shell, 1, NULL, 0, NULL, Wait); - if (tb_init() != 0) - die("tb_init"); - t_resize(); - if (s < 0) - print_error("process failed non-zero exit"); -} - -static int -fsev_init(void) -{ -#if defined(_SYS_INOTIFY_H) - inotify_fd = inotify_init(); - if (inotify_fd < 0) - return -1; -#elif defined(_SYS_EVENT_H_) - gtimeout.tv_sec = 1; - kq = kqueue(); - if (kq < 0) - return -1; -#endif - return 0; -} - -static int -addwatch(Pane *pane) -{ -#if defined(_SYS_INOTIFY_H) - return pane->inotify_wd = inotify_add_watch(inotify_fd, pane->dirn, - IN_MODIFY | IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE | - IN_ATTRIB | IN_DELETE | IN_DELETE_SELF | - IN_MOVE_SELF); -#elif defined(_SYS_EVENT_H_) - pane->event_fd = open(pane->dirn, O_RDONLY); - if (pane->event_fd < 0) - return pane->event_fd; - EV_SET(&evlist[pane->pane_id], pane->event_fd, EVFILT_VNODE, - EV_ADD | EV_CLEAR, - NOTE_DELETE | NOTE_EXTEND | NOTE_LINK | NOTE_RENAME | - NOTE_ATTRIB | NOTE_REVOKE | NOTE_WRITE, - 0, NULL); - return 0; -#endif -} - -static int -read_events(void) -{ -#if defined(_SYS_INOTIFY_H) - char *p; - ssize_t r; - struct inotify_event *event; - const size_t events = 32; - const size_t evbuflen = - events * (sizeof(struct inotify_event) + MAX_N + 1); - char buf[evbuflen]; - - if (cpane->inotify_wd < 0) - return -1; - r = read(inotify_fd, buf, evbuflen); - if (r <= 0) - return r; - - for (p = buf; p < buf + r;) { - event = (struct inotify_event *)p; - if (!event->wd) - break; - if (event->mask) { - return r; - } - - p += sizeof(struct inotify_event) + event->len; - } -#elif defined(_SYS_EVENT_H_) - return kevent(kq, evlist, 2, chlist, 2, >imeout); -#endif - return -1; -} - -static void -rmwatch(Pane *pane) -{ -#if defined(_SYS_INOTIFY_H) - if (pane->inotify_wd >= 0) - inotify_rm_watch(inotify_fd, pane->inotify_wd); -#elif defined(_SYS_EVENT_H_) - close(pane->event_fd); -#endif -} - -static void -fsev_shdn(void) -{ - pthread_cancel(fsev_thread); -#if defined(__linux__) - pthread_join(fsev_thread, NULL); -#endif - rmwatch(&panes[Left]); - rmwatch(&panes[Right]); -#if defined(_SYS_INOTIFY_H) - close(inotify_fd); -#elif defined(_SYS_EVENT_H_) - close(kq); -#endif -} - -static void -toggle_df(const Arg *arg) -{ - show_dotfiles = !show_dotfiles; - PERROR(listdir(&panes[Left])); - PERROR(listdir(&panes[Right])); - tb_present(); -} - -static void -start_filter(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - char *user_input; - user_input = ecalloc(MAX_USRI, sizeof(char)); - if (get_usrinput(user_input, MAX_USRI, "filter") < 0) { - free(user_input); - return; - } - cpane->filter = user_input; - if (listdir(cpane) < 0) - print_error("no match"); - cpane->filter = NULL; - free(user_input); -} - -static void -start_vmode(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - struct tb_event fev; - if (sel_indexes != NULL) { - free(sel_indexes); - sel_indexes = NULL; - } - - sel_indexes = ecalloc(cpane->dirc, sizeof(size_t)); - sel_indexes[0] = cpane->hdir; - cont_vmode = 0; - print_prompt("-- VISUAL --"); - tb_present(); - while (tb_poll_event(&fev) != 0) { - switch (fev.type) { - case TB_EVENT_KEY: - grabkeys(&fev, vkeys, vkeyslen); - if (cont_vmode == -1) - return; - tb_present(); - break; - } - } -} - -static void -exit_vmode(const Arg *arg) -{ - refresh_pane(cpane); - add_hi(cpane, cpane->hdir - 1); - cont_vmode = -1; -} - -static void -start_change(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - struct tb_event fev; - - cont_change = 0; - print_prompt("c [womf]"); - tb_present(); - while (tb_poll_event(&fev) != 0) { - switch (fev.type) { - case TB_EVENT_KEY: - grabkeys(&fev, ckeys, ckeyslen); - if (cont_change == -1) - return; - tb_present(); - break; - } - } -} - -static void -exit_change(const Arg *arg) -{ - cont_change = -1; - print_info(cpane, NULL); -} - -static void -selup(const Arg *arg) -{ - mv_ver(arg); - print_prompt("-- VISUAL --"); - int index = abs(cpane->hdir - sel_indexes[0]); - - if (cpane->hdir < sel_indexes[0]) { - sel_indexes[index] = cpane->hdir; - add_hi(cpane, sel_indexes[index]); - } else if (index < cpane->dirc) { - sel_indexes[index + 1] = 0; - } - if (cpane->dirc >= scrheight || - cpane->hdir <= 1) { /* rehighlight all if scrolling */ - selref(); - } -} - -static void -seldwn(const Arg *arg) -{ - mv_ver(arg); - print_prompt("-- VISUAL --"); - int index = abs(cpane->hdir - sel_indexes[0]); - - if (cpane->hdir > sel_indexes[0]) { - sel_indexes[index] = cpane->hdir; - add_hi(cpane, sel_indexes[index] - 2); - } else { - sel_indexes[index + 1] = 0; - } - if (cpane->dirc >= scrheight || - cpane->hdir >= cpane->dirc) { /* rehighlight all if scrolling */ - selref(); - } -} - -static void -selall(const Arg *arg) -{ - int i; - for (i = 0; i < cpane->dirc; i++) { - sel_indexes[i] = i + 1; - } - selref(); -} - -static void -selref(void) -{ - int i; - for (i = 0; i < cpane->dirc; i++) { - if (sel_indexes[i] < (scrheight + cpane->firstrow) && - sel_indexes[i] > - cpane->firstrow) { /* checks if in the frame of the directories */ - add_hi(cpane, sel_indexes[i] - 1); - } - } -} - -static void -selcalc(void) -{ - int j; - sel_len = 0; - - for (j = 0; j < cpane->dirc; j++) { /* calculate used selection size */ - if (sel_indexes[j] != 0) - sel_len++; - else - break; - } -} - -static void -free_files(void) -{ - size_t i; - - if (sel_files != NULL) { - for (i = 0; i < sel_len; i++) { - free(sel_files[i]); - sel_files[i] = NULL; - } - free(sel_files); - sel_files = NULL; - } -} - -static void -init_files(void) -{ - size_t i; - free_files(); - - selcalc(); - sel_files = ecalloc(sel_len, sizeof(char *)); - - for (i = 0; i < sel_len; i++) { - sel_files[i] = ecalloc(MAX_P, sizeof(char)); - strncpy(sel_files[i], cpane->direntr[sel_indexes[i] - 1].name, - MAX_P); - } -} - -static void -selynk(const Arg *arg) -{ - init_files(); - refresh_pane(cpane); - add_hi(cpane, cpane->hdir - 1); - print_status(cprompt, "%zu files are yanked", sel_len); - cont_vmode = -1; -} - -static void -seldel(const Arg *arg) -{ - char *inp_conf; - - inp_conf = ecalloc(delconf_len, sizeof(char)); - if ((get_usrinput(inp_conf, delconf_len, "delete files(s) (%s) ?", - delconf) < 0) || - (strncmp(inp_conf, delconf, delconf_len) != 0)) { - free(inp_conf); - return; /* canceled by user or wrong inp_conf */ - } - free(inp_conf); - - init_files(); - - if (spawn(rm_cmd, rm_cmd_len, sel_files, sel_len, NULL, DontWait) < 0) - print_error(strerror(errno)); - else - print_status(cprompt, "%zu files are deleted", sel_len); - - free_files(); - cont_vmode = -1; -} - -static void -paste(const Arg *arg) -{ - if (sel_files == NULL) { - print_error("nothing to paste"); - return; - } - - if (spawn(cp_cmd, cp_cmd_len, sel_files, sel_len, cpane->dirn, - DontWait) < 0) - print_error(strerror(errno)); - else - print_status(cprompt, "%zu files are copied", sel_len); - - free_files(); -} - -static void -selmv(const Arg *arg) -{ - if (sel_files == NULL) { - print_error("nothing to move"); - return; - } - - if (spawn(mv_cmd, mv_cmd_len, sel_files, sel_len, cpane->dirn, - DontWait) < 0) - print_error(strerror(errno)); - else - print_status(cprompt, "%zu files are moved", sel_len); - - free_files(); -} - -static void -rname(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - char new_name[MAX_P]; - char *input_name; - - input_name = ecalloc(MAX_N, sizeof(char)); - - if (get_usrinput(input_name, MAX_N, "rename: %s", - basename(CURSOR(cpane).name)) < 0) { - exit_change(0); - free(input_name); - return; - } - - if (snprintf(new_name, MAX_P, "%s/%s", cpane->dirn, input_name) < 0) { - free(input_name); - print_error(strerror(errno)); - return; - } - - char *rename_cmd[] = { "mv", CURSOR(cpane).name, new_name }; - PERROR(spawn(rename_cmd, 3, NULL, 0, NULL, DontWait) < 0); - - free(input_name); - exit_change(0); -} - -static void -chngo(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - char *input_og; - char *tmp[1]; - - input_og = ecalloc(MAX_N, sizeof(char)); - - if (get_usrinput(input_og, MAX_N, "OWNER:GROUP %s", - basename(CURSOR(cpane).name)) < 0) { - exit_change(0); - free(input_og); - return; - } - - tmp[0] = input_og; - if (spawn(chown_cmd, chown_cmd_len, tmp, 1, CURSOR(cpane).name, - DontWait) < 0) { - print_error(strerror(errno)); - return; - } - - free(input_og); - exit_change(0); -} - -static void -chngm(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - char *input_og; - char *tmp[1]; - - input_og = ecalloc(MAX_N, sizeof(char)); - - if (get_usrinput(input_og, MAX_N, "chmod %s", - basename(CURSOR(cpane).name)) < 0) { - exit_change(0); - free(input_og); - return; - } - - tmp[0] = input_og; - if (spawn(chmod_cmd, chmod_cmd_len, tmp, 1, CURSOR(cpane).name, - DontWait) < 0) { - print_error(strerror(errno)); - return; - } - - free(input_og); - exit_change(0); -} - -static void -chngf(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - char *input_og; - char *tmp[1]; - - input_og = ecalloc(MAX_N, sizeof(char)); - - if (get_usrinput(input_og, MAX_N, CHFLAG " %s", - basename(CURSOR(cpane).name)) < 0) { - exit_change(0); - free(input_og); - return; - } - - tmp[0] = input_og; - if (spawn(chflags_cmd, chflags_cmd_len, tmp, 1, CURSOR(cpane).name, - DontWait) < 0) { - print_error(strerror(errno)); - return; - } - - free(input_og); - exit_change(0); -} - -static void -dupl(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - char new_name[MAX_P]; - char *input_name; - - input_name = ecalloc(MAX_N, sizeof(char)); - - if (get_usrinput(input_name, MAX_N, "new name: %s", - basename(CURSOR(cpane).name)) < 0) { - free(input_name); - return; - } - - if (snprintf(new_name, MAX_P, "%s/%s", cpane->dirn, input_name) < 0) { - free(input_name); - print_error(strerror(errno)); - return; - } - - char *tmp[1]; - tmp[0] = CURSOR(cpane).name; - if (spawn(cp_cmd, cp_cmd_len, tmp, 1, new_name, DontWait) < 0) { - print_error(strerror(errno)); - return; - } - - free(input_name); -} - -static void -yank(const Arg *arg) -{ - if (cpane->dirc < 1) - return; - - free_files(); - sel_len = 1; - sel_files = ecalloc(sel_len, sizeof(char *)); - sel_files[0] = ecalloc(MAX_P, sizeof(char)); - strncpy(sel_files[0], CURSOR(cpane).name, MAX_P); - print_status(cprompt, "1 file is yanked", sel_len); -} - -static void -switch_pane(const Arg *arg) -{ - if (cpane->dirc > 0) - rm_hi(cpane, cpane->hdir - 1); - cpane = &panes[pane_idx ^= 1]; - if (cpane->dirc > 0) { - add_hi(cpane, cpane->hdir - 1); - print_info(cpane, NULL); - } else { - clear_status(); - } -} - -static void -quit(const Arg *arg) -{ - if (cont_vmode == -1) { /* check if selection was allocated */ - free(sel_indexes); - if (sel_files != NULL) - free_files(); - } - free(panes[Left].direntr); - free(panes[Right].direntr); - fsev_shdn(); - tb_shutdown(); - exit(EXIT_SUCCESS); -} - -static void -grabkeys(struct tb_event *event, Key *key, size_t max_keys) -{ - size_t i; - - for (i = 0; i < max_keys; i++) { - if (event->ch != 0) { - if (event->ch == key[i].evkey.ch) { - key[i].func(&key[i].arg); - return; - } - } else if (event->key != 0) { - if (event->key == key[i].evkey.key) { - key[i].func(&key[i].arg); - return; - } - } - } -} - -void * -read_th(void *arg) -{ - struct timespec tim; - tim.tv_sec = 0; - tim.tv_nsec = 5000000L; /* 0.005 sec */ - - while (1) - if (read_events() > READEVSZ) { - kill(main_pid, SIGUSR1); - nanosleep(&tim, NULL); - } - return arg; -} - -static void -start_ev(void) -{ - struct tb_event ev; - - while (tb_poll_event(&ev) != 0) { - switch (ev.type) { - case TB_EVENT_KEY: - grabkeys(&ev, nkeys, nkeyslen); - tb_present(); - break; - case TB_EVENT_RESIZE: - t_resize(); - break; - default: - break; - } - } - tb_shutdown(); -} - -static void -refresh_pane(Pane *pane) -{ - size_t y, dyn_max, start_from; - hwidth = (twidth / 2) - 4; - Cpair col; - - y = 1; - start_from = pane->firstrow; - dyn_max = MIN(pane->dirc, (scrheight - 1) + pane->firstrow); - - /* print each entry in directory */ - while (start_from < dyn_max) { - get_hicol(&col, pane->direntr[start_from].mode); - print_row(pane, start_from, col); - start_from++; - y++; - } - - if (pane->dirc > 0) - print_info(pane, NULL); - else - clear_status(); - - /* print current directory title */ - pane->dircol.fg |= TB_BOLD; - printf_tb(pane->x_srt, 0, pane->dircol, " %.*s", hwidth, pane->dirn); -} - -static void -set_direntr(Pane *pane, struct dirent *entry, DIR *dir, char *filter) -{ - int i; - char *tmpfull; - struct stat status; - -#define ADD_ENTRY \ - tmpfull = get_fullpath(pane->dirn, entry->d_name); \ - strncpy(pane->direntr[i].name, tmpfull, MAX_N); \ - if (lstat(tmpfull, &status) == 0) { \ - pane->direntr[i].size = status.st_size; \ - pane->direntr[i].mode = status.st_mode; \ - pane->direntr[i].group = status.st_gid; \ - pane->direntr[i].user = status.st_uid; \ - pane->direntr[i].dt = status.st_mtime; \ - } \ - i++; \ - free(tmpfull); - - i = 0; - pane->direntr = - erealloc(pane->direntr, (10 + pane->dirc) * sizeof(Entry)); - while ((entry = readdir(dir)) != 0) { - if (show_dotfiles == 1) { - if (entry->d_name[0] == '.' && - (entry->d_name[1] == '\0' || - entry->d_name[1] == '.')) - continue; - } else { - if (entry->d_name[0] == '.') - continue; - } - - if (filter == NULL) { - ADD_ENTRY - } else if (filter != NULL) { - if (strcasestr(entry->d_name, filter) != NULL) { - ADD_ENTRY - } - } - } - - pane->dirc = i; -} - -static int -listdir(Pane *pane) -{ - DIR *dir; - struct dirent *entry; - int filtercount = 0; - size_t oldc = pane->dirc; - - pane->dirc = 0; - - dir = opendir(pane->dirn); - if (dir == NULL) - return -1; - - /* get content and filter sum */ - while ((entry = readdir(dir)) != 0) { - if (pane->filter != NULL) { - if (strcasestr(entry->d_name, pane->filter) != NULL) - filtercount++; - } else { /* no filter */ - pane->dirc++; - } - } - - if (pane->filter == NULL) { - clear_pane(pane); - pane->dirc -= 2; - } - - if (pane->filter != NULL) { - if (filtercount > 0) { - pane->dirc = filtercount; - clear_pane(pane); - pane->hdir = 1; - } else if (filtercount == 0) { - if (closedir(dir) < 0) - return -1; - pane->dirc = oldc; - return -1; - } - } - - /* print current directory title */ - pane->dircol.fg |= TB_BOLD; - printf_tb(pane->x_srt, 0, pane->dircol, " %.*s", hwidth, pane->dirn); - - if (pane->filter == NULL) /* dont't watch when filtering */ - if (addwatch(pane) < 0) - print_error("can't add watch"); - - /* empty directory */ - if (pane->dirc == 0) { - clear_status(); - if (closedir(dir) < 0) - return -1; - return 0; - } - - rewinddir(dir); /* reset position */ - set_direntr( - pane, entry, dir, pane->filter); /* create array of entries */ - qsort(pane->direntr, pane->dirc, sizeof(Entry), sort_name); - refresh_pane(pane); - - if (pane->hdir > pane->dirc) - pane->hdir = pane->dirc; - - if (pane == cpane && pane->dirc > 0) - add_hi(pane, pane->hdir - 1); - - if (closedir(dir) < 0) - return -1; - return 0; -} - -static void -t_resize(void) -{ - tb_clear(); - draw_frame(); - panes[Left].x_end = (twidth / 2) - 1; - panes[Right].x_end = twidth - 1; - panes[Right].x_srt = (twidth / 2) + 2; - refresh_pane(&panes[Left]); - refresh_pane(&panes[Right]); - if (cpane->dirc > 0) - add_hi(cpane, cpane->hdir - 1); - tb_present(); -} - -static void -get_editor(void) -{ - editor[0] = getenv("EDITOR"); - editor[1] = NULL; - - if (editor[0] == NULL) - editor[0] = fed; -} - -static void -get_shell(void) -{ - shell[0] = getenv("SHELL"); - shell[1] = NULL; - - if (shell[0] == NULL) - shell[0] = sh; -} - -static void -set_panes(void) -{ - char *home; - char cwd[MAX_P]; - - home = getenv("HOME"); - if (home == NULL) - home = "/"; - if ((getcwd(cwd, sizeof(cwd)) == NULL)) - strncpy(cwd, home, MAX_P); - - pane_idx = Left; /* cursor pane */ - cpane = &panes[pane_idx]; - - panes[Left].pane_id = 0; - panes[Left].x_srt = 2; - panes[Left].x_end = (twidth / 2) - 1; - panes[Left].dircol = cpanell; - panes[Left].firstrow = 0; - panes[Left].direntr = ecalloc(0, sizeof(Entry)); - strncpy(panes[Left].dirn, cwd, MAX_P); - panes[Left].hdir = 1; - panes[Left].inotify_wd = -1; - panes[Left].parent_row = 1; - - panes[Right].pane_id = 1; - panes[Right].x_srt = (twidth / 2) + 2; - panes[Right].x_end = twidth - 1; - panes[Right].dircol = cpanelr; - panes[Right].firstrow = 0; - panes[Right].direntr = ecalloc(0, sizeof(Entry)); - strncpy(panes[Right].dirn, home, MAX_P); - panes[Right].hdir = 1; - panes[Right].inotify_wd = -1; - panes[Right].parent_row = 1; -} - -static void -draw_frame(void) -{ - int i; - theight = tb_height(); - twidth = tb_width(); - hwidth = (twidth / 2) - 4; - scrheight = theight - 2; - - /* 2 horizontal lines */ - for (i = 1; i < twidth - 1; ++i) { - tb_change_cell(i, 0, u_hl, cframe.fg, cframe.bg); - tb_change_cell(i, theight - 2, u_hl, cframe.fg, cframe.bg); - } - - /* 4 vertical lines */ - for (i = 1; i < theight - 1; ++i) { - tb_change_cell(0, i, u_vl, cframe.fg, cframe.bg); - tb_change_cell( - (twidth - 1) / 2, i - 1, u_vl, cframe.fg, cframe.bg); - tb_change_cell(((twidth - 1) / 2) + 1, i - 1, u_vl, cframe.fg, - cframe.bg); - tb_change_cell(twidth - 1, i, u_vl, cframe.fg, cframe.bg); - } - - /* 4 corners */ - tb_change_cell(0, 0, u_cnw, cframe.fg, cframe.bg); - tb_change_cell(twidth - 1, 0, u_cne, cframe.fg, cframe.bg); - tb_change_cell(0, theight - 2, u_csw, cframe.fg, cframe.bg); - tb_change_cell(twidth - 1, theight - 2, u_cse, cframe.fg, cframe.bg); - - /* 2 middel top and bottom */ - tb_change_cell((twidth - 1) / 2, 0, u_mn, cframe.fg, cframe.bg); - tb_change_cell( - (twidth - 1) / 2, theight - 2, u_ms, cframe.fg, cframe.bg); -} - -void -th_handler(int num) -{ - if (fork_pid > 0) /* while forking don't listdir() */ - return; - (void)num; - PERROR(listdir(&panes[Left])); - PERROR(listdir(&panes[Right])); - tb_present(); -} - -static int -start_signal(void) -{ - struct sigaction sa; - - main_pid = getpid(); - sa.sa_handler = th_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - return sigaction(SIGUSR1, &sa, NULL); -} - -static void -refresh(const Arg *arg) -{ - kill(main_pid, SIGWINCH); -} - -static void -start(void) -{ - switch (tb_init()) { - case TB_EFAILED_TO_OPEN_TTY: - die("TB_EFAILED_TO_OPEN_TTY"); - break; - case TB_EUNSUPPORTED_TERMINAL: - die("TB_EUNSUPPORTED_TERMINAL"); - break; - case TB_EPIPE_TRAP_ERROR: - die("TB_EUNSUPPORTED_TERMINAL"); - break; - case 0: - break; - default: - die("UNKNOWN FAILURE"); - } - - if (tb_select_output_mode(TB_OUTPUT_256) != TB_OUTPUT_256) - if (tb_select_output_mode(TB_OUTPUT_NORMAL) != TB_OUTPUT_NORMAL) - die("output error"); - draw_frame(); - set_panes(); - get_editor(); - get_shell(); - PERROR(start_signal() < 0); - PERROR(fsev_init() < 0); - PERROR(listdir(&panes[Left]) < 0); - PERROR(listdir(&panes[Right]) < 0); - tb_present(); - - pthread_create(&fsev_thread, NULL, read_th, NULL); - start_ev(); -} - -int -main(int argc, char *argv[]) -{ -#if defined(__OpenBSD__) - if (pledge("cpath exec getpw proc rpath stdio tmppath tty wpath", - NULL) == -1) - die("pledge"); -#endif /* __OpenBSD__ */ - if (argc == 1) - start(); - else if (argc == 2 && strncmp("-v", argv[1], 2) == 0) - die("sfm-" VERSION); - else - die("usage: sfm [-v]"); - return 0; -} |