winpl

LD_PRELOAD-based X11 window manipulator
git clone https://git.sinitax.com/sinitax/winpl
Log | Files | Refs | LICENSE | sfeed.txt

loader.c (3860B)


      1#include <linux/limits.h>
      2#include <sys/stat.h>
      3#include <err.h>
      4#include <dirent.h>
      5#include <limits.h>
      6#include <unistd.h>
      7#include <string.h>
      8#include <stdio.h>
      9#include <stdbool.h>
     10#include <stdlib.h>
     11
     12#define ARRLEN(x) (sizeof(x) / sizeof((x)[0]))
     13
     14static const char *libpath = "/tmp/winpl.so";
     15
     16extern char _binary_winpl_so_start[];
     17extern char _binary_winpl_so_end[];
     18
     19extern char **environ;
     20
     21void
     22usage(int rc, bool full)
     23{
     24	fprintf(stderr, "Usage: winpl [OPT].. -- CMD [ARG]..\n");
     25	if (!full) exit(rc);
     26	fprintf(stderr, "\n");
     27	fprintf(stderr, "  -ow              Always write preload library\n");
     28	fprintf(stderr, "  [-ax|-ay] POS    Absolute window position\n");
     29	fprintf(stderr, "  [-mx|-my] POS    Window position relative to monitor\n");
     30	fprintf(stderr, "  [-rx|-ry] SCALE  Window position relative to monitor\n"
     31	                "                   as a factor of monitor size\n");
     32	fprintf(stderr, "  [-aw|-ah] SIZE   Absolute window width/height\n");
     33	fprintf(stderr, "  [-rw|-rh] SCALE  Window size relative to monitor\n");
     34	fprintf(stderr, "  -c               Center window on monitor\n");
     35	fprintf(stderr, "  -f               Tag window as dialog (floating)\n");
     36	fprintf(stderr, "  -mn SCREEN       Select monitor based on number\n");
     37	fprintf(stderr, "  -mp              Select monitor based on cursor\n");
     38	fprintf(stderr, "  -mf              Select monitor based on focus\n");
     39	fprintf(stderr, "  -ni              Window does not take input (focus)\n");
     40	fprintf(stderr, "  -name NAME       Set window name\n");
     41	fprintf(stderr, "\n");
     42	exit(rc);
     43}
     44
     45void
     46write_lib(const char *filename)
     47{
     48	FILE *file;
     49	size_t size;
     50	void *data;
     51
     52	file = fopen(filename, "wb+");
     53	if (!file) err(1, "fopen %s", filename);
     54
     55	data = (void*) _binary_winpl_so_start;
     56	size = (size_t) (_binary_winpl_so_end - _binary_winpl_so_start);
     57
     58	if (fwrite(data, size, 1, file) != 1)
     59		errx(1, "failed to write winpl lib");
     60
     61	fclose(file);
     62}
     63
     64int
     65main(int argc, char *const *argv)
     66{
     67	char *const *cmd_argv = NULL;
     68	char *const *arg;
     69	char pathbuf[PATH_MAX];
     70	struct stat st;
     71	bool overwrite = false;
     72
     73	if (argc < 1) return 0;
     74
     75	for (arg = argv + 1; *arg; arg++) {
     76		if (!strcmp(*arg, "-h")) {
     77			usage(0, true);
     78		} else if (!strcmp(*arg, "-ax")) {
     79			setenv("WINPL_WX", *++arg, true);
     80		} else if (!strcmp(*arg, "-ay")) {
     81			setenv("WINPL_WY", *++arg, true);
     82		} else if (!strcmp(*arg, "-mx")) {
     83			setenv("WINPL_MWX", *++arg, true);
     84		} else if (!strcmp(*arg, "-my")) {
     85			setenv("WINPL_MWY", *++arg, true);
     86		} else if (!strcmp(*arg, "-rx")) {
     87			setenv("WINPL_RWX", *++arg, true);
     88		} else if (!strcmp(*arg, "-ry")) {
     89			setenv("WINPL_RWY", *++arg, true);
     90		} else if (!strcmp(*arg, "-aw")) {
     91			setenv("WINPL_WW", *++arg, true);
     92		} else if (!strcmp(*arg, "-ah")) {
     93			setenv("WINPL_WH", *++arg, true);
     94		} else if (!strcmp(*arg, "-rw")) {
     95			setenv("WINPL_RWW", *++arg, true);
     96		} else if (!strcmp(*arg, "-rh")) {
     97			setenv("WINPL_RWH", *++arg, true);
     98		} else if (!strcmp(*arg, "-c")) {
     99			setenv("WINPL_CENTER", "1", true);
    100		} else if (!strcmp(*arg, "-f")) {
    101			setenv("WINPL_FLOAT", "1", true);
    102		} else if (!strcmp(*arg, "-mn")) {
    103			setenv("WINPL_MON_NUM", *++arg, true);
    104		} else if (!strcmp(*arg, "-mp")) {
    105			setenv("WINPL_MON_PTR", "1", true);
    106		} else if (!strcmp(*arg, "-mf")) {
    107			setenv("WINPL_MON_FOCUS", "1", true);
    108		} else if (!strcmp(*arg, "-ni")) {
    109			setenv("WINPL_NO_INPUT", "1", true);
    110		} else if (!strcmp(*arg, "-name")) {
    111			setenv("WINPL_NAME", *++arg, true);
    112		} else if (!strcmp(*arg, "-ow")) {
    113			overwrite = true;
    114		} else if (!strcmp(*arg, "--") && *(arg+1)) {
    115			cmd_argv = arg + 1;
    116			break;
    117		} else {
    118			usage(1, true);
    119		}
    120	}
    121	if (!cmd_argv) usage(1, false);
    122
    123	if (overwrite || stat(libpath, &st))
    124		write_lib(libpath);
    125
    126	setenv("LD_PRELOAD", libpath, true);
    127
    128	execvp(*cmd_argv, cmd_argv);
    129
    130	err(1, "execve %s", pathbuf);
    131}