dwm-sshawarespawn-6.2.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       dwm-sshawarespawn-6.2.diff (8820B)
       ---
            1 From fc232a3075835e01c1dab6b199ec8817d911d0be Mon Sep 17 00:00:00 2001
            2 From: blatzfab <fabian.blatz@gmail.com>
            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        argument */
           19          { MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
           20 -        { MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },
           21 +        { MODKEY|ShiftMask,             XK_Return, spawnsshaware,  {.v = termcmd } },
           22          { MODKEY,                       XK_b,      togglebar,      {0} },
           23          { MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
           24          { MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
           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 -lxcb -lxcb-res ${KVMLIB} -lprocps
           39  
           40  # flags
           41  CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
           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, isfullscreen;
           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 size);
           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",filename_qfd);
          160 +                        continue;
          161 +                }
          162 +                if (((stbuf.st_mode & S_IFMT) == S_IFDIR) && strtopid(dp->d_name, &pid)) {
          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 && checkparents(pid, process)){
          168 +                                res = calloc(strlen(cmdline)+1, sizeof(char));
          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 | PROC_FILLSTATUS | PROC_PID, &pid);
          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", "-c", sshcmdline, NULL};
          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(xcon, 1, &spec);
          266 +        xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e);
          267 +
          268 +        if (!r)
          269 +                return (pid_t)0;
          270 +
          271 +        xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r);
          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.data);
          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", 1), 0, 1, False, AnyPropertyType, &type, &format, &len, &bytes, &prop) != Success || !prop)
          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 cases are
          307   * ignored (especially on UnmapNotify's). Other types of errors call Xlibs
          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