commit 8f395b3eb5e335a32dbc3afbd82a174d999cc46c
parent 1a1ce06ac43f10d689a0f894bacd2980a41ec71b
Author: Wim Dupont <wim@wimdupont.com>
Date: Sat, 5 Jul 2025 14:07:17 +0200
added chown
Diffstat:
M | cex.c | | | 80 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | config.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'