Overview
Comment: | udpate xpriv to use sysv shmem by default; give iaia an option to generate its own types, and allow selecting between 7-bit and 8-bit encodings for ascii (defaulting to 8-bit); update mkpw to work with new iaia; update ord to add flag controlling byte length (7 or 8) for iaia's ascii mode |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
6a14de18116c33e773d7050066650a2c |
User & Date: | lexi on 2019-07-20 23:37:03 |
Other Links: | manifest | tags |
Context
2019-07-21
| ||
06:15 | add clipserv check-in: 5e680bdd13 user: lexi tags: trunk | |
2019-07-20
| ||
23:37 | udpate xpriv to use sysv shmem by default; give iaia an option to generate its own types, and allow selecting between 7-bit and 8-bit encodings for ascii (defaulting to 8-bit); update mkpw to work with new iaia; update ord to add flag controlling byte length (7 or 8) for iaia's ascii mode check-in: 6a14de1811 user: lexi tags: trunk | |
18:12 | fixes check-in: 00358989c7 user: lexi tags: trunk | |
Changes
Modified clib/iaia.c from [f7f2775d1b] to [1d0d9f385e].
1 1 /* [ʞ] iaia.c 2 2 * ~ lexi hale <lexi@hale.su> 3 3 * # include "iaia.c" 4 4 * # define _IAIA_FN_{ATOI,ITOA,ASCTOI,ITOASC} 5 + * _IAIA_EXP_ASCFORM 5 6 * : typedef iaia_word_type, 6 7 * iaia_error_type 7 8 * : enum iaia_e_domain, 8 9 * iaia_e_base, 9 10 * iaia_e_overflow 10 11 * ? arbitrary-base integer conversion functions 11 12 */ ................................................................................ 18 19 #endif 19 20 #ifndef _IAIA_FN_ASCTOI 20 21 # define _IAIA_FN_ASCTOI asctoi 21 22 #endif 22 23 #ifndef _IAIA_FN_ITOASC 23 24 # define _IAIA_FN_ITOASC itoasc 24 25 #endif 26 +#ifndef _IAIA_EXP_ASCFORM 27 +/* this is an expression that will be evaluated to 28 + * determine whether to compress ascii to a 7-bit 29 + * representation or to store it in 8-bit space. 30 + * 1 = 7-bit (compressed) 31 + * 0 = 8-bit (uncompressed) */ 32 +# define _IAIA_EXP_ASCFORM (0) 33 +#endif 25 34 26 35 enum /* constants */ { 36 + base7bit = 128, 27 37 28 38 /* ascii address space */ 29 39 numspace = (0x39 - 0x30) + 1, /* 10 */ 30 40 alphaspace = (0x5a - 0x41) + 1, /* 26 */ 31 41 smallalphaspace = (0x7a - 0x61) + 1, /* 26 */ 32 42 33 43 /* base representations */ 34 44 imaxbase = numspace + alphaspace, /* 36 */ 35 45 maxbase = imaxbase + smallalphaspace /* 62 */ 36 46 }; 47 +#ifndef _IAIA_EXTERNAL_TYPES 48 + typedef enum iaia_error_type { 49 + iaia_e_ok, 50 + iaia_e_domain, 51 + iaia_e_base, 52 + iaia_e_overflow, 53 + } iaia_error_type; 54 + typedef unsigned long long iaia_word_type; 55 +#endif 37 56 38 57 /* -- string to integer converters -- */ 39 58 40 59 iaia_error_type _IAIA_FN_ASCTOI(const char* s, iaia_word_type* ret) { 41 60 iaia_word_type val = 0; 42 - enum { base = 128 }; 43 61 44 62 for (;*s!=null;++s) { 45 63 uint8_t v = *s; 46 - if (v > base) return iaia_e_domain; 64 + if (v > base7bit) return iaia_e_domain; 47 65 48 - val *= base; 66 + if (_IAIA_EXP_ASCFORM) 67 + val *= base7bit; 68 + else val <<= 8; 69 + 49 70 val += v; 50 71 } 51 72 52 73 *ret = val; 53 74 return ok; 54 75 } 55 76 ................................................................................ 106 127 iaia_error_type _IAIA_FN_ITOASC(iaia_word_type val, const char* buf_start, char* buf_end, char** newbuf) { 107 128 char* ptr = buf_end; 108 129 109 130 *ptr-- = 0; 110 131 while(val > 0) { 111 132 if (ptr < buf_start) return iaia_e_overflow; 112 133 iaia_word_type rem = val % 128; 113 - val /= 128; 134 + if (_IAIA_EXP_ASCFORM) 135 + val /= base7bit; 136 + else val >>= 8; 114 137 *ptr-- = (char)rem; 115 138 } 116 139 117 140 if (newbuf != null) *newbuf = ptr + 1; 118 141 return ok; 119 142 } 120 143
Modified mkpw.c from [2857320b30] to [4060441d9a].
56 56 enum /* iaia errors */ { 57 57 iaia_e_ok = ok, 58 58 iaia_e_base = fail, 59 59 iaia_e_domain = fail, 60 60 iaia_e_overflow = fail, 61 61 }; 62 62 #define _IAIA_FN_ATOI katoi 63 +#define _IAIA_EXTERNAL_TYPES 63 64 #include "clib/iaia.c" 64 65 65 66 typedef enum { 66 67 tbl_ok = ok, tbl_error = fail 67 68 } tbl_error_type; 68 69 typedef unsigned char tbl_word_type; 69 70 #include "clib/tbl.c"
Modified ord.c from [8e7c9355c5] to [9504e2c85c].
81 81 arg_asc, 82 82 83 83 arg_bin, arg_trn, arg_oct, arg_dec, 84 84 arg_duo, arg_hex, arg_b32, arg_b64, 85 85 86 86 switch_prefix, param_prefix, 87 87 switch_lowercase, 88 + switch_7bit, 88 89 89 90 arg_ebcdic, 90 91 }; 91 92 92 93 word bases[] = { 93 94 [arg_asc] = 0, 94 95 [arg_bin] = 2, ................................................................................ 124 125 {arg_duo, "duo"}, {arg_duo, "duodecimal"}, 125 126 {arg_hex, "hex"}, {arg_hex, "hexadecimal"}, 126 127 127 128 {arg_hex, "b32"}, {arg_hex, "base32"}, /* not padded! */ 128 129 129 130 {switch_prefix, "-p"}, {switch_prefix, "--prefix"}, 130 131 {switch_lowercase, "-l"}, {switch_lowercase, "--lowercase"}, 132 + {switch_7bit, "-7"}, {switch_7bit, "--7bit"}, 131 133 {param_prefix, "-m"}, {param_prefix, "--manual-prefix"}, 132 134 133 135 {arg_ebcdic, "ebcdic"}, 134 136 }; 135 137 136 138 /* import the conversion utilities */ 137 139 typedef bad iaia_error_type; ................................................................................ 138 140 typedef word iaia_word_type; 139 141 enum /* iaia synonyms */ { 140 142 iaia_e_ok = ok, 141 143 iaia_e_domain = bad_domain, 142 144 iaia_e_base = bad_base, 143 145 iaia_e_overflow = bad_overflow, 144 146 }; 147 +bool ascii_7bit = false; 148 +#define _IAIA_EXP_ASCFORM ascii_7bit 149 +#define _IAIA_EXTERNAL_TYPES 145 150 #include "clib/iaia.c" 146 151 147 152 bad run(const int argc, const char** argv) { 148 153 # ifndef _POSIX_IO 149 154 /* fuck your buffering, it only ever makes 150 155 * things worse */ 151 156 setvbuf(stdout,null,_IONBF); ................................................................................ 161 166 162 167 bool raw = false; 163 168 bool prefix = false; 164 169 bool lowercase = false; 165 170 166 171 for (const char** arg = argv + 1; *arg != null; ++arg) { 167 172 uint8_t tblval; 168 - if (*arg[0] == '%') { ++ *arg; goto number; } else 173 + if (*arg[0] == '`') { ++ *arg; goto number; } else 169 174 if (!raw && (tblget(sz(argtbl),argtbl, *arg, &tblval) == ok)) { 170 175 enum argument symbol = (enum argument) tblval; 171 176 switch (symbol) { 172 177 case arg_to: { 173 178 if (curset == set_out) return bad_syntax; 174 179 else curset = set_out; 175 180 } break; ................................................................................ 197 202 forposix(pfxstrlen = strlen(pfxstr)); 198 203 ++arg; 199 204 } break; 200 205 201 206 /* specify an automatic output prefix */ 202 207 case switch_prefix: { prefix = true; pfxstr = null; } break; 203 208 case switch_lowercase: { lowercase = true; } break; 209 + case switch_7bit: { ascii_7bit = true; } break; 204 210 205 211 default: { 206 212 /* assume base shorthand */ 207 213 base[curset] = bases[symbol]; 208 214 } 209 215 } 210 216 } else /* bad_find */ number: { ................................................................................ 286 292 lit("base") " " box("0-9") plus OR "asc")), 287 293 }, ints[] = { 288 294 p("default base: \x1b[94m.+\x1b[m"), 289 295 p("binary literal: "lit("0b") box("01") plus), 290 296 p("ternary literal: "lit("0t") box("012") plus), 291 297 p("hex literal: "lit("0x") box("0-9A-Fa-f") plus), 292 298 p("ascii literal: "lit("@") "\x1b[94m.+\x1b[m"), 293 - p("interpret any string (e.g. a keyword) as integer: " lit("%") box("0-9A-Za-z") plus), 299 + p("interpret any string (e.g. a keyword) as integer: " lit("`") box("0-9A-Za-z") plus), 294 300 }, opts[] = { 295 301 p("-p --prefix : print known prefix codes on output strings"), 296 302 p("-m --manual-prefix: specify a manual prefix to print before each number"), 297 303 p("-l --lowercase : prefer lowercase for case-insensitive bases"), 304 + p("-7 --7bit : encode ascii in 7-bit space instead of keeping the"), 305 + p(" eighth empty bit. if this option is used, ascii"), 306 + p(" strings will be maximally compact, but will not match"), 307 + p(" the way they are stored in computer memory!"), 308 + /* p("-u --utf : allow non-ascii input"), */ 298 309 }; 299 310 # undef p 300 311 # undef OR 301 312 # undef plus 302 313 303 314 # define hl_on "\x1b[;1m" 304 315 # define hl_off "\x1b[m"
Modified xpriv.c from [6369b6f0d6] to [48a3d17a7c].
68 68 69 69 TODO add a randomizer call that works on BSD 70 70 71 71 TODO document flags 72 72 73 73 TODO implement/remove lock flag 74 74 75 - TODO add flag to bring window to current desktop */ 75 + TODO add flag to bring window to current desktop 76 + 77 + TODO rewrite using sysv shmem */ 76 78 77 79 78 80 #include <pwd.h> 79 81 #include <pty.h> 80 82 #include <fcntl.h> 81 83 #include <unistd.h> 82 84 #include <stdint.h> ................................................................................ 83 85 #include <stdlib.h> 84 86 #include <string.h> 85 87 #include <signal.h> 86 88 #include <sys/mman.h> 87 89 #include <sys/stat.h> 88 90 #include <sys/wait.h> 89 91 #include <sys/types.h> 92 +#include <sys/shm.h> 90 93 #include <X11/Xlib.h> 91 94 #include <errno.h> 92 -#include <sys/random.h> //TODO bsd compat 95 +#include <sys/random.h> 93 96 94 -#define shmem_prefix "/k.xpriv:" 97 +#ifdef _RAND_SYSCALL 98 +# include <sys/syscall.h> 99 +# define getrandom(a,b,c) syscall(SYS_getrandom,a,b,c) 100 + /* this is necessary on certain platforms due to 101 + * certainly ungodly libc issues, i think. */ 102 +#endif 95 103 96 -typedef enum { false, true } bool; 104 +#ifdef _SHM_LINUX 105 + /* xpriv was originally written with linux shared 106 + * memory in mind, because i'm an idiot. i've since 107 + * redesigned it to use the superior old sysv shm 108 + * api that works on every other unix, not just 109 + * linux, but if for some ungodly reason you want 110 + * to use the linux one, then just pass -D_SHM_LINUX */ 111 +# define shmem_prefix "/k.xpriv:" 112 +# define shmlinux(...) __VA_ARGS__ 113 +# define shmsysv(...) 114 +#else 115 +# define shmlinux(...) 116 +# define shmsysv(...) __VA_ARGS__ 117 +#endif 118 + 119 +enum /* constants */ { 120 + false = 0, true = 1, 121 + shmsysv(shmem_key = 0x53373EC3,) /* ye olde magique numbre */ 122 +}; 123 + 124 +typedef _Bool bool; 97 125 enum mode { mode_usage, mode_go, mode_register, 98 126 mode_kill, mode_lock }; 99 127 100 128 enum res { ok, fail_parse, fail_arg, fail_opt, fail_shm, 101 129 fail_mem, fail_pty, fail_nop, fail_win, 102 130 fail_wid, fail_x11}; 103 131 enum res bad(enum res code) { ................................................................................ 146 174 void sigusr(int a) { if (global -> op == mode_kill) run = false; } 147 175 void sigterm(int a) { run = false; } 148 176 149 177 void spawn(pid_t ssha, const char* const sockn) { 150 178 if (ssha = fork()) { 151 179 char pid_s_buf[16]; 152 180 char* pid_s = itoa(ssha, pid_s_buf, sizeof(pid_s_buf)); 153 - while (access(sockn, F_OK)); 154 - // avoid nasty race condition 181 + while (access(sockn, F_OK)); // avoid nasty race condition 155 182 setenv("SSH_AGENT_PID", pid_s, true); 156 183 setenv("SSH_AUTH_SOCK", sockn, true); 157 184 global -> agent = ssha; 158 185 } else { 159 186 close(1); close(0); 160 - execlp("ssh-agent","ssh-agent","-D", "-a",sockn,0); 187 + execlp("ssh-agent","ssh-agent","-D","-a",sockn,0); 161 188 } 162 189 } 163 190 164 -enum res register_window(const char* const id, bool weak, const char* const name) { 191 +enum res register_window(shmlinux(const char* const id,) bool weak, const char* name) { 165 192 // the id field denotes the path to the shared memory 166 193 // in use, and allows the user to have multiple 167 194 // contexts by creating aliases to the binary 168 - int fd = shm_open(id, O_CREAT | O_EXCL | O_RDWR, 0600); 169 - ftruncate(fd, sizeof(struct signal)); 170 - if (fd == -1) return fail_shm; 171 - 172 - struct signal* s = mmap(0, sizeof(struct signal), 173 - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 174 - if(s == MAP_FAILED) return fail_mem; 175 - else global = s; 195 + struct signal* s; 196 + shmlinux ({ 197 + int fd = shm_open(id, O_CREAT | O_EXCL | O_RDWR, 0600); 198 + ftruncate(fd, sizeof(struct signal)); 199 + if (fd == -1) return fail_shm; 200 + 201 + s = mmap(0, sizeof(struct signal), 202 + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 203 + if(s == MAP_FAILED) return fail_mem; 204 + else global = s; 205 + }) shmsysv (int shmem; 206 + shmem = shmget(shmem_key, sizeof (struct signal), IPC_CREAT | 0777); 207 + if (shmem == -1) return fail_shm; 208 + 209 + s = shmat(shmem, 0,0); 210 + 211 + if (s == (void*)-1) return fail_mem; 212 + else global = s; 213 + ) 176 214 177 215 Display* xdpy = XOpenDisplay(NULL); 178 216 Atom xvital; 179 217 180 218 /* x11 */ { 181 219 if (xdpy == NULL) return fail_win; 182 220 Window win; ................................................................................ 206 244 } 207 245 208 246 if(s -> op == mode_kill) { 209 247 kill(s -> pid, SIGTERM); 210 248 } 211 249 kill(s -> agent, SIGTERM); 212 250 sigprocmask(SIG_BLOCK, &mask, NULL); 213 - shm_unlink(id); 251 + 252 + shmlinux(shm_unlink(id)); 253 + shmsysv({ 254 + struct shmid_ds bleh; /* ?? */ 255 + shmctl(shmem, IPC_RMID, &bleh); 256 + }) 257 + 214 258 if (!weak) { 215 259 XDeleteProperty(xdpy,s -> wid,xvital); 216 260 XSync(xdpy,false); 217 261 } 218 262 XCloseDisplay(xdpy); 219 263 } else { 220 264 // now we start ssh-agent and set the proper environment 221 265 // variables 222 266 pid_t ssha; 223 267 224 268 if (name == NULL) { 225 269 /* messy part */ 226 270 const char* tmp; //tmpdir defined? 227 - if (!(tmp = getenv("TMPDIR"))) tmp = "/tmp"; 271 + if (!(tmp = getenv("XDG_RUNTIME_DIR"))) 272 + if (!(tmp = getenv("TMPDIR"))) tmp = "/tmp"; 273 + 228 274 size_t tmpsz = strlen(tmp); 229 275 230 276 char sockn[tmpsz + 1 + sizeof "ssh." 231 277 + 11]; 232 278 strcpy(sockn, tmp); 233 279 sockn[tmpsz] = '/'; 234 280 strcpy(sockn+tmpsz+1,"ssh."); ................................................................................ 241 287 // assuming ascii… 242 288 for(uint8_t*i=rndid;i<rndid+11;++i) { 243 289 *i = '0' + (*i % (25 * 2 + 10)); 244 290 if (*i > '9') *i += 7; 245 291 if (*i > 'Z') *i += ('a' - 'Z'); 246 292 } 247 293 248 - spawn(ssha, sockn); 249 - } else spawn(ssha, name); 294 + name = sockn; 295 + } 296 + spawn(ssha, name); 250 297 251 298 pid_t sad; 252 299 int p; 253 300 if (sad = fork()) { 254 301 int added; 255 302 waitpid(sad, &added, 0); 256 303 if (added == 0) { 257 304 if (weak == false) { 258 305 XChangeProperty(xdpy,s -> wid,xvital,xvital,8,PropModeReplace,"\01", 1); 259 306 XSync(xdpy,false); 260 307 } 261 308 write(1,"\033c",3); 262 309 execlp("fish","fish",NULL); 263 - } else { return ok; } 310 + } 264 311 } else { 265 312 execlp("ssh-add","ssh-add",NULL); 266 313 } 267 314 } 268 315 269 - return ok; // this is kind of pointless but w/e 316 + return ok; 270 317 } 271 -enum res kill_window(const char* id) { 272 - int fd = shm_open(id, O_RDWR, 0600); 273 - if (fd == -1) return fail_nop; 318 +enum res kill_window(shmlinux(const char* id)) { 319 + struct signal* s; 320 + shmlinux({ 321 + int fd = shm_open(id, O_RDWR, 0600); 322 + if (fd == -1) return fail_nop; 274 323 275 - struct signal* s = mmap(0, sizeof(struct signal), 276 - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 277 - if(s == MAP_FAILED) return fail_mem; 324 + s = mmap(0, sizeof(struct signal), 325 + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 326 + if(s == MAP_FAILED) return fail_mem; 327 + }) shmsysv (int shmem; { 328 + shmem = shmget(shmem_key, sizeof(struct signal), 0); 329 + if (shmem == -1) return fail_nop; 330 + s = shmat(shmem,0,0); 331 + if (s == (void*)-1) return fail_mem; 332 + }) 333 + 334 + shmsysv({ 335 + struct shmid_ds bleh; /* ?? */ 336 + shmctl(shmem, IPC_RMID, &bleh); 337 + }) 278 338 279 339 s -> op = mode_kill; 280 340 kill(s -> pid, SIGUSR1); 281 341 282 342 return ok; 283 343 } 284 344 enum res activate_window(Window w) { ................................................................................ 299 359 if(!XSendEvent(dpy, DefaultRootWindow(dpy), False, mask, &ev)) return fail_x11; 300 360 301 361 XSync(dpy,false); 302 362 return ok; 303 363 } 304 364 305 365 int main(int sz, char** argv) { 366 + char* binname = "xpriv"; 367 + if(sz > 0) binname = argv[0]; 368 + 306 369 enum mode op = mode_go; 307 370 bool init_weak = false; 308 371 const char* init_named = NULL; 309 372 310 373 for(int i = 1; i<sz; ++i) { 311 374 char* v = argv[i]; 312 375 if (*v != '-') return bad(fail_arg); ................................................................................ 325 388 seen_string_arg = true; 326 389 ++ i; break; 327 390 default: return bad(fail_opt); 328 391 } 329 392 if(opt[1] != 0) { ++opt; goto read_opt; } 330 393 } 331 394 332 - size_t nsz; 333 - const char* basename = argv[0], *p; 334 - for (p = argv[0]; *p!=0; ++p) { 335 - if(*p == '/') basename = p + 1; 336 - } 337 - nsz = p - basename; 338 - char shid[nsz + sizeof shmem_prefix]; 339 - strncpy(shid,shmem_prefix,sizeof shmem_prefix); 340 - strncpy(shid + sizeof shmem_prefix - 1, basename, nsz); 341 - shid[nsz + sizeof shmem_prefix - 1] = 0; 395 + shmlinux( 396 + size_t nsz; 397 + const char* basename = argv[0], *p; 398 + for (p = binname; *p!=0; ++p) { 399 + if(*p == '/') basename = p + 1; 400 + } 401 + nsz = p - basename; 402 + char shid[nsz + sizeof shmem_prefix]; 403 + strncpy(shid,shmem_prefix,sizeof shmem_prefix); 404 + strncpy(shid + sizeof shmem_prefix - 1, basename, nsz); 405 + shid[nsz + sizeof shmem_prefix - 1] = 0; 406 + ) shmsysv ({ 407 + /* TODO: implement ability to have multiple 408 + * keys based on the name of the binary */ 409 + }) 342 410 343 - if (op == mode_go) { 344 - int fd; 345 - if ((fd = shm_open(shid, O_RDWR, 0600)) == -1) { 411 + tryagain: if (op == mode_go) { 412 + int shm; 413 + if ((shm = shmlinux( 414 + shm_open(shid, O_RDWR, 0600) 415 + ) shmsysv ( 416 + shmget(shmem_key,sizeof (struct signal),0) 417 + )) == -1) { 346 418 const char* args[] = { 347 419 "urxvtc", "-bg", "[90]#4b0024", 348 420 "-e", argv[0], 349 421 (init_weak?"-aw":"-a"), 0, 0, 0}; 350 422 351 423 const uint8_t argsz = sizeof args/sizeof(const char*); 352 424 if (init_named != NULL) { 353 425 args[argsz - 3] = "-n"; // im sorry 354 426 args[argsz - 2] = init_named; 355 427 } 356 428 357 429 execvp("urxvtc", (char* const*)args); 358 430 } else { 359 - struct signal*s = mmap(0, sizeof(struct signal), 360 - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 431 + struct signal*s = shmlinux( 432 + mmap(0, sizeof(struct signal), PROT_READ | PROT_WRITE, MAP_SHARED, shm, 0) 433 + ) shmsysv ( 434 + shmat(shm, 0, 0) 435 + ); 436 + 437 + struct shmid_ds stat; 438 + shmctl(shm, IPC_STAT, &stat); 439 + if (stat.shm_nattch == 0) { 440 + /* if the shm segment is not attached to any 441 + * process, it's a relic that needs to be 442 + * cleaned up before we do anything else. on 443 + * a sane OS, there would be built-in non- 444 + * persistence mechanisms for shared mem, but 445 + * alas, as you already know, POSIX */ 446 + shmctl(shm, IPC_RMID, &stat); 447 + goto tryagain; 448 + } 449 + 450 + if (s == shmlinux(MAP_FAILED) shmsysv((void*)-1)) 451 + return bad(fail_mem); 361 452 return bad(activate_window(s->wid)); 362 453 } 363 454 } else if (op == mode_register) 364 - return bad(register_window(shid,init_weak,init_named)); 455 + return bad(register_window(shmlinux(shid,) init_weak,init_named)); 365 456 else if (op == mode_kill) 366 - return bad(kill_window(shid)); 457 + return bad(kill_window(shmlinux(shid))); 367 458 else if (op == mode_usage) { 368 459 write(1,"\e[1musage:\e[0m ",15); 369 460 write(1, argv[0], strlen(argv[0])); 370 461 write(1, " [-aklw [arg]]\n",16); 371 462 return fail_parse; 372 463 } 373 464 } 374 465