/* [ʞ] safekill.c * - lexi hale * a utility to make it harder to accidentally nuke * important windows from i3 or whatever. * released under affero general public license */ #include #include #include #include #include #include typedef enum { false, true } bool; char* isvital(char* str) { start: // tail calls for dipshits if (*str != '{') { if (*str == 0) return 0; ++str; goto start; } else { if (str[1] == 'V' && str[2] == '}') return str; else { ++str; goto start; } } } int main(const int argc, const char** argv) { Display *display; Window focus; int revert; bool active; enum { vitalize, devitalize, hardkill, softkill } op; if (argc > 3) goto usage; if (argc == 1) op = softkill, active = true; else { if (argc == 2) active = true; else active = false; if (argv[1][0] == '-' && argv[1][2] == 0) { // opt is short switch switch (argv[1][1]) { // opt char // make window mission-critical case 'v': op = vitalize; break; // make window acceptable loss case 'c': op = devitalize; break; // liquidate by any means necessary case 'q': op = hardkill; break; // with all due respect sir what the fuck default: goto usage; } } else goto usage; } display = XOpenDisplay(NULL); if (active) { XGetInputFocus(display, &focus, &revert); } else { unsigned long temp = strtoul(argv[2], NULL, 0); if (errno == EINVAL || errno == ERANGE) goto usage; if (temp == 0) goto usage; focus = (Window)temp; } if(op == hardkill) { XDestroyWindow(display,focus); XSync(display,false); return 0; } XClassHint xclh; if (XGetClassHint(display,focus,&xclh)) { char* v; if(v = isvital(xclh.res_class)) { if (op == vitalize) return 0; // nothing need be done else if (op == devitalize) { strcpy(v, v+3); XSetClassHint(display,focus,&xclh); XSync(display,false); } else if (op == softkill) { printf("softkill forbidden\n"); return 1; // ACCESS DENIED } } else { if (op == vitalize) { size_t sz=strlen(xclh.res_class); // TODO: remove double-walk xclh.res_class=realloc(xclh.res_class, sz+4); xclh.res_class[sz]='{'; xclh.res_class[sz+1]='V'; xclh.res_class[sz+2]='}'; xclh.res_class[sz+3]=0; XSetClassHint(display,focus,&xclh); XSync(display,false); } else if (op == devitalize) return 0; else if (op == softkill) { // ice that motherfucker XDestroyWindow(display,focus); XSync(display,false); return 3; } } } else { printf("\x1b[1merror:\x1b[m bad window\n"); goto usage; } return 0; usage: #define info "\x1b[34m-- " #define param "\x1b[32m" #define eol "\x1b[m\n" #define bold "\x1b[1m" #define nl " " printf(bold "usage:\x1b[0m %s " " " info "kill active window if non-vital" eol nl "%1$s -v " param "[id] " info "make [id] or active window vital" eol nl "%1$s -c " param "[id] " info "clear vital flag on [id] or active window" eol nl "%1$s -q " param "[id] " info "'emergency' kill w/o reference to vital flag" eol, argv[0]); return 1; }