cex

C/Curses file EXplorer
git clone git://git.wimdupont.com/cex.git
Log | Files | Refs | README | LICENSE

commit 8f395b3eb5e335a32dbc3afbd82a174d999cc46c
parent 1a1ce06ac43f10d689a0f894bacd2980a41ec71b
Author: Wim Dupont <wim@wimdupont.com>
Date:   Sat,  5 Jul 2025 14:07:17 +0200

added chown

Diffstat:
Mcex.c | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mconfig.def.h | 1+
2 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/cex.c b/cex.c @@ -82,6 +82,7 @@ static void next_search(void); static void prev_search(void); static void free_dirwin(DirWin *dirwin); static void run_command(size_t size, const char *fmt, ...); +static void run_sudo_command(size_t size, const char *fmt, ...); static void clean(void); static void fatal(const char *fmt, ...); static bool is_dir(DirWin *dirwin, size_t index); @@ -95,6 +96,8 @@ static int read_command(char *buf, size_t bufsize, const char *cmd); static int make_file(void); static int make_dir(void); static int make_mod(void); +static int make_chown(void); +static int sudo_chown(char *owner, char *group, long namelen); static void make_access(void); static void make_open_default(void); static void make_mime_default(const char *mime, const char *app); @@ -892,6 +895,9 @@ combo_make(int key) case KEY_COMBO_MAKE_MOD: make_mod(); break; + case KEY_COMBO_MAKE_CHOWN: + make_chown(); + break; case KEY_COMBO_MAKE_ACCESS: make_access(); break; @@ -1330,6 +1336,38 @@ run_command(size_t size, const char *fmt, ...) system(cmd); } +void +run_sudo_command(size_t size, const char *fmt, ...) +{ + va_list ap; + char cmd[size]; + sigset_t set; + + endwin(); + + if (sigemptyset (&set) == -1) + fatal("Sigemptyset failed."); + if (sigaddset(&set, SIGWINCH) == -1) + fatal("Sigaddset failed."); + if (sigprocmask(SIG_BLOCK, &set, NULL) != 0) + fatal("Blocking sigprocmask failed."); + + va_start(ap, fmt); + vsnprintf(cmd, size, fmt, ap); + va_end(ap); + + system(cmd); + + if (sigprocmask(SIG_UNBLOCK, &set, NULL) != 0) + fatal("Unblocking sigprocmask failed."); + + erase(); + refresh(); + wrefresh(parwin.window); + wrefresh(curwin.window); + wrefresh(childwin.window); +} + int make_dir(void) { @@ -1428,6 +1466,48 @@ make_mod(void) return 0; } +int +make_chown(void) +{ + struct passwd *usr; + struct group *grp; + long len = sysconf(_SC_LOGIN_NAME_MAX); + char owner[len], group[len]; + + prompt_answer(owner, len, "Owner name? "); + prompt_answer(group, len, "Group name? "); + + if ((usr = getpwnam(owner)) == NULL) + return -1; + + if ((grp = getgrnam(group)) == NULL) + return -1; + + if ((chown(curwin.winfiles[curwin.highlight].d_name, usr->pw_uid, grp->gr_gid)) != 0) { + switch (errno) { + case EACCES: + case EPERM: + sudo_chown(owner, group, len); + break; + default: + return errno; + } + } + return 0; +} + +int +sudo_chown(char *owner, char *group, long namelen) +{ + size_t cmdsize; + char pathbuf[PATH_MAX], *cmdfmt = "sudo chown %s:%s %s"; + + cmdsize = namelen*2 + PATH_MAX + strlen(cmdfmt); + run_sudo_command(cmdsize, cmdfmt, owner, group, get_fullpath(pathbuf, &curwin, curwin.highlight)); + + return 0; +} + void make_access(void) { diff --git a/config.def.h b/config.def.h @@ -48,6 +48,7 @@ #define KEY_COMBO_MAKE_FILE 'f' #define KEY_COMBO_MAKE_DIR 'd' #define KEY_COMBO_MAKE_MOD 'm' +#define KEY_COMBO_MAKE_CHOWN 'c' #define KEY_COMBO_MAKE_ACCESS 'a' #define KEY_COMBO_MAKE_OPEN_DEFAULT 'o'