| dwm-sshawarespawn-6.2.diff - sites - public wiki contents of suckless.org | |
| git clone git://git.suckless.org/sites | |
| Log | |
| Files | |
| Refs | |
| --- | |
| dwm-sshawarespawn-6.2.diff (8820B) | |
| --- | |
| 1 From fc232a3075835e01c1dab6b199ec8817d911d0be Mon Sep 17 00:00:00 2001 | |
| 2 From: blatzfab <[email protected]> | |
| 3 Date: Fri, 16 Oct 2020 09:44:24 +0000 | |
| 4 Subject: [PATCH] Adds ssh aware spawn command | |
| 5 | |
| 6 --- | |
| 7 config.def.h | 2 +- | |
| 8 config.mk | 3 +- | |
| 9 dwm.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++ | |
| 10 3 files changed, 177 insertions(+), 2 deletions(-) | |
| 11 | |
| 12 diff --git a/config.def.h b/config.def.h | |
| 13 index 1c0b587..1121d4d 100644 | |
| 14 --- a/config.def.h | |
| 15 +++ b/config.def.h | |
| 16 @@ -62,7 +62,7 @@ static const char *termcmd[] = { "st", NULL }; | |
| 17 static Key keys[] = { | |
| 18 /* modifier key function argu… | |
| 19 { MODKEY, XK_p, spawn, {.v … | |
| 20 - { MODKEY|ShiftMask, XK_Return, spawn, {.v … | |
| 21 + { MODKEY|ShiftMask, XK_Return, spawnsshaware, {.v … | |
| 22 { MODKEY, XK_b, togglebar, {0} … | |
| 23 { MODKEY, XK_j, focusstack, {.i … | |
| 24 { MODKEY, XK_k, focusstack, {.i … | |
| 25 diff --git a/config.mk b/config.mk | |
| 26 index 6d36cb7..5272bdc 100644 | |
| 27 --- a/config.mk | |
| 28 +++ b/config.mk | |
| 29 @@ -19,10 +19,11 @@ FREETYPELIBS = -lfontconfig -lXft | |
| 30 FREETYPEINC = /usr/include/freetype2 | |
| 31 # OpenBSD (uncomment) | |
| 32 #FREETYPEINC = ${X11INC}/freetype2 | |
| 33 +#KVMLIB = -lkvm | |
| 34 | |
| 35 # includes and libs | |
| 36 INCS = -I${X11INC} -I${FREETYPEINC} | |
| 37 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} | |
| 38 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxc… | |
| 39 | |
| 40 # flags | |
| 41 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSIO… | |
| 42 diff --git a/dwm.c b/dwm.c | |
| 43 index 4465af1..bd35817 100644 | |
| 44 --- a/dwm.c | |
| 45 +++ b/dwm.c | |
| 46 @@ -28,6 +28,8 @@ | |
| 47 #include <stdlib.h> | |
| 48 #include <string.h> | |
| 49 #include <unistd.h> | |
| 50 +#include <proc/readproc.h> | |
| 51 +#include <sys/stat.h> | |
| 52 #include <sys/types.h> | |
| 53 #include <sys/wait.h> | |
| 54 #include <X11/cursorfont.h> | |
| 55 @@ -40,6 +42,12 @@ | |
| 56 #include <X11/extensions/Xinerama.h> | |
| 57 #endif /* XINERAMA */ | |
| 58 #include <X11/Xft/Xft.h> | |
| 59 +#include <X11/Xlib-xcb.h> | |
| 60 +#include <xcb/res.h> | |
| 61 +#ifdef __OpenBSD__ | |
| 62 +#include <sys/sysctl.h> | |
| 63 +#include <kvm.h> | |
| 64 +#endif /* __OpenBSD */ | |
| 65 | |
| 66 #include "drw.h" | |
| 67 #include "util.h" | |
| 68 @@ -93,6 +101,7 @@ struct Client { | |
| 69 int bw, oldbw; | |
| 70 unsigned int tags; | |
| 71 int isfixed, isfloating, isurgent, neverfocus, oldstate, isfull… | |
| 72 + pid_t pid; | |
| 73 Client *next; | |
| 74 Client *snext; | |
| 75 Monitor *mon; | |
| 76 @@ -156,6 +165,8 @@ static void clientmessage(XEvent *e); | |
| 77 static void configure(Client *c); | |
| 78 static void configurenotify(XEvent *e); | |
| 79 static void configurerequest(XEvent *e); | |
| 80 +static char* checksshsession(pid_t process); | |
| 81 +static int checkparents(pid_t pid, pid_t target); | |
| 82 static Monitor *createmon(void); | |
| 83 static void destroynotify(XEvent *e); | |
| 84 static void detach(Client *c); | |
| 85 @@ -171,6 +182,7 @@ static void focusmon(const Arg *arg); | |
| 86 static void focusstack(const Arg *arg); | |
| 87 static int getrootptr(int *x, int *y); | |
| 88 static long getstate(Window w); | |
| 89 +static int getprocinfo(pid_t pid, proc_t *procinfo); | |
| 90 static int gettextprop(Window w, Atom atom, char *text, unsigned int si… | |
| 91 static void grabbuttons(Client *c, int focused); | |
| 92 static void grabkeys(void); | |
| 93 @@ -206,6 +218,8 @@ static void seturgent(Client *c, int urg); | |
| 94 static void showhide(Client *c); | |
| 95 static void sigchld(int unused); | |
| 96 static void spawn(const Arg *arg); | |
| 97 +static void spawnsshaware(const Arg *arg); | |
| 98 +static int strtopid(char *s, pid_t *pid); | |
| 99 static void tag(const Arg *arg); | |
| 100 static void tagmon(const Arg *arg); | |
| 101 static void tile(Monitor *); | |
| 102 @@ -229,6 +243,7 @@ static void updatewmhints(Client *c); | |
| 103 static void view(const Arg *arg); | |
| 104 static Client *wintoclient(Window w); | |
| 105 static Monitor *wintomon(Window w); | |
| 106 +static pid_t winpid(Window w); | |
| 107 static int xerror(Display *dpy, XErrorEvent *ee); | |
| 108 static int xerrordummy(Display *dpy, XErrorEvent *ee); | |
| 109 static int xerrorstart(Display *dpy, XErrorEvent *ee); | |
| 110 @@ -267,6 +282,7 @@ static Display *dpy; | |
| 111 static Drw *drw; | |
| 112 static Monitor *mons, *selmon; | |
| 113 static Window root, wmcheckwin; | |
| 114 +static xcb_connection_t *xcon; | |
| 115 | |
| 116 /* configuration, allows nested code to access above variables */ | |
| 117 #include "config.h" | |
| 118 @@ -575,6 +591,63 @@ configurenotify(XEvent *e) | |
| 119 } | |
| 120 } | |
| 121 | |
| 122 +int | |
| 123 +checkparents(pid_t pid, pid_t target) | |
| 124 +{ | |
| 125 + proc_t *pinf = calloc(1, sizeof(proc_t)); | |
| 126 + pid_t current = pid; | |
| 127 + | |
| 128 + while(current!=(pid_t)0 && current!=(pid_t)1 && current!=target… | |
| 129 + getprocinfo(current, pinf); | |
| 130 + current = pinf->ppid; | |
| 131 + } | |
| 132 + freeproc(pinf); | |
| 133 + if(current==target) | |
| 134 + return 1; | |
| 135 + return 0; | |
| 136 +} | |
| 137 + | |
| 138 +char* | |
| 139 +checksshsession(pid_t process) | |
| 140 +{ | |
| 141 + struct dirent *dp; | |
| 142 + DIR *dfd; | |
| 143 + const char *dir = "/proc"; | |
| 144 + char filename_qfd[100] ; | |
| 145 + pid_t pid; | |
| 146 + proc_t* process_info = calloc(1, sizeof(proc_t)); | |
| 147 + struct stat stbuf; | |
| 148 + char* res = 0; | |
| 149 + | |
| 150 + if ((dfd = opendir(dir)) == NULL) { | |
| 151 + fprintf(stderr, "Can't open %s\n", dir); | |
| 152 + freeproc(process_info); | |
| 153 + return 0; | |
| 154 + } | |
| 155 + | |
| 156 + while ((dp = readdir(dfd)) != NULL && res == 0) { | |
| 157 + sprintf( filename_qfd , "%s/%s",dir,dp->d_name); | |
| 158 + if(stat(filename_qfd,&stbuf ) == -1) { | |
| 159 + fprintf(stderr, "Unable to stat file: %s\n",fil… | |
| 160 + continue; | |
| 161 + } | |
| 162 + if (((stbuf.st_mode & S_IFMT) == S_IFDIR) && strtopid(d… | |
| 163 + getprocinfo(pid, process_info); | |
| 164 + if(!process_info->cmdline) | |
| 165 + continue; | |
| 166 + char* cmdline = *process_info->cmdline; | |
| 167 + if(strncmp("ssh ", cmdline, 4) == 0 && checkpar… | |
| 168 + res = calloc(strlen(cmdline)+1, sizeof(… | |
| 169 + strcpy(res, cmdline); | |
| 170 + } | |
| 171 + } | |
| 172 + } | |
| 173 + freeproc(process_info); | |
| 174 + free(dfd); | |
| 175 + return res; | |
| 176 +} | |
| 177 + | |
| 178 + | |
| 179 void | |
| 180 configurerequest(XEvent *e) | |
| 181 { | |
| 182 @@ -899,6 +972,19 @@ getstate(Window w) | |
| 183 return result; | |
| 184 } | |
| 185 | |
| 186 +int | |
| 187 +getprocinfo(pid_t pid, proc_t *procinfo) | |
| 188 +{ | |
| 189 + int res = 1; | |
| 190 + if(!procinfo) | |
| 191 + return 0; | |
| 192 + PROCTAB *pt_ptr = openproc(PROC_FILLARG | PROC_EDITCMDLCVT | PR… | |
| 193 + if(readproc(pt_ptr, procinfo)) | |
| 194 + res = 0; | |
| 195 + closeproc(pt_ptr); | |
| 196 + return res; | |
| 197 +} | |
| 198 + | |
| 199 int | |
| 200 gettextprop(Window w, Atom atom, char *text, unsigned int size) | |
| 201 { | |
| 202 @@ -1023,6 +1109,7 @@ manage(Window w, XWindowAttributes *wa) | |
| 203 | |
| 204 c = ecalloc(1, sizeof(Client)); | |
| 205 c->win = w; | |
| 206 + c->pid = winpid(w); | |
| 207 /* geometry */ | |
| 208 c->x = c->oldx = wa->x; | |
| 209 c->y = c->oldy = wa->y; | |
| 210 @@ -1636,6 +1723,38 @@ sigchld(int unused) | |
| 211 while (0 < waitpid(-1, NULL, WNOHANG)); | |
| 212 } | |
| 213 | |
| 214 +void | |
| 215 +spawnsshaware(const Arg *arg) | |
| 216 +{ | |
| 217 + if(selmon->sel) { | |
| 218 + char* sshcmdline = checksshsession(selmon->sel->pid); | |
| 219 + if(sshcmdline){ | |
| 220 + const char* sshcmd[] = {"st", "-e", "/bin/bash"… | |
| 221 + Arg a = {.v=sshcmd}; | |
| 222 + spawn(&a); | |
| 223 + free(sshcmdline); | |
| 224 + }else{ | |
| 225 + spawn(arg); | |
| 226 + } | |
| 227 + }else{ | |
| 228 + spawn(arg); | |
| 229 + } | |
| 230 +} | |
| 231 + | |
| 232 +int | |
| 233 +strtopid(char *s, pid_t *pid) | |
| 234 +{ | |
| 235 + long result = 0; | |
| 236 + char *eptr; | |
| 237 + if(!pid) | |
| 238 + return 0; | |
| 239 + result = strtol(s, &eptr, 10); | |
| 240 + if((eptr && *eptr!='\0') || errno == ERANGE) | |
| 241 + return 0; | |
| 242 + *pid=(pid_t) result; | |
| 243 + return 1; | |
| 244 +} | |
| 245 + | |
| 246 void | |
| 247 spawn(const Arg *arg) | |
| 248 { | |
| 249 @@ -2074,6 +2193,59 @@ wintomon(Window w) | |
| 250 return selmon; | |
| 251 } | |
| 252 | |
| 253 + | |
| 254 +pid_t | |
| 255 +winpid(Window w) | |
| 256 +{ | |
| 257 + pid_t result = 0; | |
| 258 + | |
| 259 + #ifdef __linux__ | |
| 260 + xcb_res_client_id_spec_t spec = {0}; | |
| 261 + spec.client = w; | |
| 262 + spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; | |
| 263 + | |
| 264 + xcb_generic_error_t *e = NULL; | |
| 265 + xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(… | |
| 266 + xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_… | |
| 267 + | |
| 268 + if (!r) | |
| 269 + return (pid_t)0; | |
| 270 + | |
| 271 + xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids… | |
| 272 + for (; i.rem; xcb_res_client_id_value_next(&i)) { | |
| 273 + spec = i.data->spec; | |
| 274 + if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID… | |
| 275 + uint32_t *t = xcb_res_client_id_value_value(i.d… | |
| 276 + result = *t; | |
| 277 + break; | |
| 278 + } | |
| 279 + } | |
| 280 + | |
| 281 + free(r); | |
| 282 + | |
| 283 + if (result == (pid_t)-1) | |
| 284 + result = 0; | |
| 285 + | |
| 286 + #endif /* __linux__ */ | |
| 287 + | |
| 288 + #ifdef __OpenBSD__ | |
| 289 + Atom type; | |
| 290 + int format; | |
| 291 + unsigned long len, bytes; | |
| 292 + unsigned char *prop; | |
| 293 + pid_t ret; | |
| 294 + | |
| 295 + if (XGetWindowProperty(dpy, w, XInternAtom(dpy, "_NET_WM_PID", … | |
| 296 + return 0; | |
| 297 + | |
| 298 + ret = *(pid_t*)prop; | |
| 299 + XFree(prop); | |
| 300 + result = ret; | |
| 301 + | |
| 302 + #endif /* __OpenBSD__ */ | |
| 303 + return result; | |
| 304 +} | |
| 305 + | |
| 306 /* There's no way to check accesses to destroyed windows, thus those ca… | |
| 307 * ignored (especially on UnmapNotify's). Other types of errors call Xl… | |
| 308 * default error handler, which may call exit. */ | |
| 309 @@ -2135,6 +2307,8 @@ main(int argc, char *argv[]) | |
| 310 fputs("warning: no locale support\n", stderr); | |
| 311 if (!(dpy = XOpenDisplay(NULL))) | |
| 312 die("dwm: cannot open display"); | |
| 313 + if (!(xcon = XGetXCBConnection(dpy))) | |
| 314 + die("dwm: cannot get xcb connection\n"); | |
| 315 checkotherwm(); | |
| 316 setup(); | |
| 317 #ifdef __OpenBSD__ | |
| 318 -- | |
| 319 2.28.0 | |
| 320 |