Index: clib/iaia.c ================================================================== --- clib/iaia.c +++ clib/iaia.c @@ -1,9 +1,10 @@ /* [ʞ] iaia.c * ~ lexi hale * # include "iaia.c" * # define _IAIA_FN_{ATOI,ITOA,ASCTOI,ITOASC} + * _IAIA_EXP_ASCFORM * : typedef iaia_word_type, * iaia_error_type * : enum iaia_e_domain, * iaia_e_base, * iaia_e_overflow @@ -20,12 +21,21 @@ # define _IAIA_FN_ASCTOI asctoi #endif #ifndef _IAIA_FN_ITOASC # define _IAIA_FN_ITOASC itoasc #endif +#ifndef _IAIA_EXP_ASCFORM +/* this is an expression that will be evaluated to + * determine whether to compress ascii to a 7-bit + * representation or to store it in 8-bit space. + * 1 = 7-bit (compressed) + * 0 = 8-bit (uncompressed) */ +# define _IAIA_EXP_ASCFORM (0) +#endif enum /* constants */ { + base7bit = 128, /* ascii address space */ numspace = (0x39 - 0x30) + 1, /* 10 */ alphaspace = (0x5a - 0x41) + 1, /* 26 */ smallalphaspace = (0x7a - 0x61) + 1, /* 26 */ @@ -32,22 +42,33 @@ /* base representations */ imaxbase = numspace + alphaspace, /* 36 */ maxbase = imaxbase + smallalphaspace /* 62 */ }; +#ifndef _IAIA_EXTERNAL_TYPES + typedef enum iaia_error_type { + iaia_e_ok, + iaia_e_domain, + iaia_e_base, + iaia_e_overflow, + } iaia_error_type; + typedef unsigned long long iaia_word_type; +#endif /* -- string to integer converters -- */ iaia_error_type _IAIA_FN_ASCTOI(const char* s, iaia_word_type* ret) { iaia_word_type val = 0; - enum { base = 128 }; for (;*s!=null;++s) { uint8_t v = *s; - if (v > base) return iaia_e_domain; + if (v > base7bit) return iaia_e_domain; - val *= base; + if (_IAIA_EXP_ASCFORM) + val *= base7bit; + else val <<= 8; + val += v; } *ret = val; return ok; @@ -108,11 +129,13 @@ *ptr-- = 0; while(val > 0) { if (ptr < buf_start) return iaia_e_overflow; iaia_word_type rem = val % 128; - val /= 128; + if (_IAIA_EXP_ASCFORM) + val /= base7bit; + else val >>= 8; *ptr-- = (char)rem; } if (newbuf != null) *newbuf = ptr + 1; return ok; Index: mkpw.c ================================================================== --- mkpw.c +++ mkpw.c @@ -58,10 +58,11 @@ iaia_e_base = fail, iaia_e_domain = fail, iaia_e_overflow = fail, }; #define _IAIA_FN_ATOI katoi +#define _IAIA_EXTERNAL_TYPES #include "clib/iaia.c" typedef enum { tbl_ok = ok, tbl_error = fail } tbl_error_type; Index: ord.c ================================================================== --- ord.c +++ ord.c @@ -83,10 +83,11 @@ arg_bin, arg_trn, arg_oct, arg_dec, arg_duo, arg_hex, arg_b32, arg_b64, switch_prefix, param_prefix, switch_lowercase, + switch_7bit, arg_ebcdic, }; word bases[] = { @@ -126,10 +127,11 @@ {arg_hex, "b32"}, {arg_hex, "base32"}, /* not padded! */ {switch_prefix, "-p"}, {switch_prefix, "--prefix"}, {switch_lowercase, "-l"}, {switch_lowercase, "--lowercase"}, + {switch_7bit, "-7"}, {switch_7bit, "--7bit"}, {param_prefix, "-m"}, {param_prefix, "--manual-prefix"}, {arg_ebcdic, "ebcdic"}, }; @@ -140,10 +142,13 @@ iaia_e_ok = ok, iaia_e_domain = bad_domain, iaia_e_base = bad_base, iaia_e_overflow = bad_overflow, }; +bool ascii_7bit = false; +#define _IAIA_EXP_ASCFORM ascii_7bit +#define _IAIA_EXTERNAL_TYPES #include "clib/iaia.c" bad run(const int argc, const char** argv) { # ifndef _POSIX_IO /* fuck your buffering, it only ever makes @@ -163,11 +168,11 @@ bool prefix = false; bool lowercase = false; for (const char** arg = argv + 1; *arg != null; ++arg) { uint8_t tblval; - if (*arg[0] == '%') { ++ *arg; goto number; } else + if (*arg[0] == '`') { ++ *arg; goto number; } else if (!raw && (tblget(sz(argtbl),argtbl, *arg, &tblval) == ok)) { enum argument symbol = (enum argument) tblval; switch (symbol) { case arg_to: { if (curset == set_out) return bad_syntax; @@ -199,10 +204,11 @@ } break; /* specify an automatic output prefix */ case switch_prefix: { prefix = true; pfxstr = null; } break; case switch_lowercase: { lowercase = true; } break; + case switch_7bit: { ascii_7bit = true; } break; default: { /* assume base shorthand */ base[curset] = bases[symbol]; } @@ -288,15 +294,20 @@ p("default base: \x1b[94m.+\x1b[m"), p("binary literal: "lit("0b") box("01") plus), p("ternary literal: "lit("0t") box("012") plus), p("hex literal: "lit("0x") box("0-9A-Fa-f") plus), p("ascii literal: "lit("@") "\x1b[94m.+\x1b[m"), - p("interpret any string (e.g. a keyword) as integer: " lit("%") box("0-9A-Za-z") plus), + p("interpret any string (e.g. a keyword) as integer: " lit("`") box("0-9A-Za-z") plus), }, opts[] = { p("-p --prefix : print known prefix codes on output strings"), p("-m --manual-prefix: specify a manual prefix to print before each number"), p("-l --lowercase : prefer lowercase for case-insensitive bases"), + p("-7 --7bit : encode ascii in 7-bit space instead of keeping the"), + p(" eighth empty bit. if this option is used, ascii"), + p(" strings will be maximally compact, but will not match"), + p(" the way they are stored in computer memory!"), + /* p("-u --utf : allow non-ascii input"), */ }; # undef p # undef OR # undef plus Index: xpriv.c ================================================================== --- xpriv.c +++ xpriv.c @@ -70,11 +70,13 @@ TODO document flags TODO implement/remove lock flag - TODO add flag to bring window to current desktop */ + TODO add flag to bring window to current desktop + + TODO rewrite using sysv shmem */ #include #include #include @@ -85,17 +87,43 @@ #include #include #include #include #include +#include #include #include -#include //TODO bsd compat +#include -#define shmem_prefix "/k.xpriv:" +#ifdef _RAND_SYSCALL +# include +# define getrandom(a,b,c) syscall(SYS_getrandom,a,b,c) + /* this is necessary on certain platforms due to + * certainly ungodly libc issues, i think. */ +#endif -typedef enum { false, true } bool; +#ifdef _SHM_LINUX + /* xpriv was originally written with linux shared + * memory in mind, because i'm an idiot. i've since + * redesigned it to use the superior old sysv shm + * api that works on every other unix, not just + * linux, but if for some ungodly reason you want + * to use the linux one, then just pass -D_SHM_LINUX */ +# define shmem_prefix "/k.xpriv:" +# define shmlinux(...) __VA_ARGS__ +# define shmsysv(...) +#else +# define shmlinux(...) +# define shmsysv(...) __VA_ARGS__ +#endif + +enum /* constants */ { + false = 0, true = 1, + shmsysv(shmem_key = 0x53373EC3,) /* ye olde magique numbre */ +}; + +typedef _Bool bool; enum mode { mode_usage, mode_go, mode_register, mode_kill, mode_lock }; enum res { ok, fail_parse, fail_arg, fail_opt, fail_shm, fail_mem, fail_pty, fail_nop, fail_win, @@ -148,33 +176,43 @@ void spawn(pid_t ssha, const char* const sockn) { if (ssha = fork()) { char pid_s_buf[16]; char* pid_s = itoa(ssha, pid_s_buf, sizeof(pid_s_buf)); - while (access(sockn, F_OK)); - // avoid nasty race condition + while (access(sockn, F_OK)); // avoid nasty race condition setenv("SSH_AGENT_PID", pid_s, true); setenv("SSH_AUTH_SOCK", sockn, true); global -> agent = ssha; } else { close(1); close(0); - execlp("ssh-agent","ssh-agent","-D", "-a",sockn,0); + execlp("ssh-agent","ssh-agent","-D","-a",sockn,0); } } -enum res register_window(const char* const id, bool weak, const char* const name) { +enum res register_window(shmlinux(const char* const id,) bool weak, const char* name) { // the id field denotes the path to the shared memory // in use, and allows the user to have multiple // contexts by creating aliases to the binary - int fd = shm_open(id, O_CREAT | O_EXCL | O_RDWR, 0600); - ftruncate(fd, sizeof(struct signal)); - if (fd == -1) return fail_shm; - - struct signal* s = mmap(0, sizeof(struct signal), - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if(s == MAP_FAILED) return fail_mem; - else global = s; + struct signal* s; + shmlinux ({ + int fd = shm_open(id, O_CREAT | O_EXCL | O_RDWR, 0600); + ftruncate(fd, sizeof(struct signal)); + if (fd == -1) return fail_shm; + + s = mmap(0, sizeof(struct signal), + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if(s == MAP_FAILED) return fail_mem; + else global = s; + }) shmsysv (int shmem; + shmem = shmget(shmem_key, sizeof (struct signal), IPC_CREAT | 0777); + if (shmem == -1) return fail_shm; + + s = shmat(shmem, 0,0); + + if (s == (void*)-1) return fail_mem; + else global = s; + ) Display* xdpy = XOpenDisplay(NULL); Atom xvital; /* x11 */ { @@ -208,11 +246,17 @@ if(s -> op == mode_kill) { kill(s -> pid, SIGTERM); } kill(s -> agent, SIGTERM); sigprocmask(SIG_BLOCK, &mask, NULL); - shm_unlink(id); + + shmlinux(shm_unlink(id)); + shmsysv({ + struct shmid_ds bleh; /* ?? */ + shmctl(shmem, IPC_RMID, &bleh); + }) + if (!weak) { XDeleteProperty(xdpy,s -> wid,xvital); XSync(xdpy,false); } XCloseDisplay(xdpy); @@ -222,11 +266,13 @@ pid_t ssha; if (name == NULL) { /* messy part */ const char* tmp; //tmpdir defined? - if (!(tmp = getenv("TMPDIR"))) tmp = "/tmp"; + if (!(tmp = getenv("XDG_RUNTIME_DIR"))) + if (!(tmp = getenv("TMPDIR"))) tmp = "/tmp"; + size_t tmpsz = strlen(tmp); char sockn[tmpsz + 1 + sizeof "ssh." + 11]; strcpy(sockn, tmp); @@ -243,12 +289,13 @@ *i = '0' + (*i % (25 * 2 + 10)); if (*i > '9') *i += 7; if (*i > 'Z') *i += ('a' - 'Z'); } - spawn(ssha, sockn); - } else spawn(ssha, name); + name = sockn; + } + spawn(ssha, name); pid_t sad; int p; if (sad = fork()) { int added; @@ -258,25 +305,38 @@ XChangeProperty(xdpy,s -> wid,xvital,xvital,8,PropModeReplace,"\01", 1); XSync(xdpy,false); } write(1,"\033c",3); execlp("fish","fish",NULL); - } else { return ok; } + } } else { execlp("ssh-add","ssh-add",NULL); } } - return ok; // this is kind of pointless but w/e + return ok; } -enum res kill_window(const char* id) { - int fd = shm_open(id, O_RDWR, 0600); - if (fd == -1) return fail_nop; +enum res kill_window(shmlinux(const char* id)) { + struct signal* s; + shmlinux({ + int fd = shm_open(id, O_RDWR, 0600); + if (fd == -1) return fail_nop; - struct signal* s = mmap(0, sizeof(struct signal), - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if(s == MAP_FAILED) return fail_mem; + s = mmap(0, sizeof(struct signal), + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if(s == MAP_FAILED) return fail_mem; + }) shmsysv (int shmem; { + shmem = shmget(shmem_key, sizeof(struct signal), 0); + if (shmem == -1) return fail_nop; + s = shmat(shmem,0,0); + if (s == (void*)-1) return fail_mem; + }) + + shmsysv({ + struct shmid_ds bleh; /* ?? */ + shmctl(shmem, IPC_RMID, &bleh); + }) s -> op = mode_kill; kill(s -> pid, SIGUSR1); return ok; @@ -301,10 +361,13 @@ XSync(dpy,false); return ok; } int main(int sz, char** argv) { + char* binname = "xpriv"; + if(sz > 0) binname = argv[0]; + enum mode op = mode_go; bool init_weak = false; const char* init_named = NULL; for(int i = 1; iwid)); } } else if (op == mode_register) - return bad(register_window(shid,init_weak,init_named)); + return bad(register_window(shmlinux(shid,) init_weak,init_named)); else if (op == mode_kill) - return bad(kill_window(shid)); + return bad(kill_window(shmlinux(shid))); else if (op == mode_usage) { write(1,"\e[1musage:\e[0m ",15); write(1, argv[0], strlen(argv[0])); write(1, " [-aklw [arg]]\n",16); return fail_parse; } }