Mercurial > projects > pwm
view pwm-clip.c @ 42:fb995e5d54e9 version-1
Release version 1
author | Guido Berhoerster <guido+pwm@berhoerster.name> |
---|---|
date | Tue, 20 Aug 2019 21:26:55 +0200 |
parents | 5bdea77d0c1d |
children |
line wrap: on
line source
/* * Copyright (C) 2017 Guido Berhoerster <guido+pwm@berhoerster.name> * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "compat.h" #ifdef HAVE_ERR_H #include <err.h> #endif /* HAVE_ERR_H */ #include <errno.h> #include <nettle/base64.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include "util.h" #define CHUNK_SIZE 128 static char * base64_encode(const unsigned char *src, size_t size) { char *dst = NULL; struct base64_encode_ctx b64_ctx; size_t len = 0; dst = xmalloc(BASE64_ENCODE_LENGTH(size) + BASE64_ENCODE_FINAL_LENGTH); base64_encode_init(&b64_ctx); len += base64_encode_update(&b64_ctx, (unsigned char *)dst, size, src); len += base64_encode_final(&b64_ctx, (unsigned char *)dst); dst[len] = '\0'; dst = xrealloc(dst, len + 1); return (dst); } static void set_clipboard(const char *s) { char *b64 = NULL; b64 = base64_encode((const unsigned char *)s, strlen(s)); printf("\033]52;c;%s\a\n", b64); free(b64); } static void set_clipboard_dcs_tmux(const char *s) { char *b64 = NULL; b64 = base64_encode((const unsigned char *)s, strlen(s)); printf("\033Ptmux;\033\033]52;c;%s\a\033\\", b64); free(b64); } static void set_clipboard_dcs_chunked(const char *s) { char *b64 = NULL; size_t i; b64 = base64_encode((const unsigned char *)s, strlen(s)); printf("\033P\033]52;c;"); for (i = 0; b64[i] != '\0'; i++) { if ((i > 0) && (i % CHUNK_SIZE == 0)) { printf("\033\\\033P"); } putchar(b64[i]); } printf("\a\033\\"); free(b64); } static void usage(void) { fprintf(stderr, "usage: %s\n", getprogname()); } int main(int argc, char *argv[]) { int status = EXIT_FAILURE; char *term; void (*set_clipboard_func)(const char *); int errflag = 0; int c; ssize_t len; char *s = NULL; size_t size = 0; setprogname(argv[0]); term = getenv("TERM"); if (term == NULL) { fprintf(stderr, "error: unknown terminal\n"); goto out; } else if (strncmp(term, "xterm", strlen("xterm")) == 0) { set_clipboard_func = set_clipboard; } else if (strncmp(term, "tmux", strlen("tmux")) == 0) { set_clipboard_func = set_clipboard_dcs_tmux; } else if (strncmp(term, "screen", strlen("screen")) == 0) { if (getenv("TMUX") != NULL) { set_clipboard_func = set_clipboard_dcs_tmux; } else { set_clipboard_func = set_clipboard_dcs_chunked; } } else { fprintf(stderr, "terminal does not support setting " "X11 CLIPBOARD selection\n"); goto out; } while (!errflag && (c = getopt(argc, argv, "h")) != -1) { switch (c) { case 'h': usage(); exit(EXIT_SUCCESS); default: errflag = 1; } } if (errflag || (optind + 1 < argc)) { usage(); exit(EXIT_USAGE); } errno = 0; len = getline(&s, &size, stdin); if (len < 0) { if (errno == 0) { fprintf(stderr, "failed to read line\n"); goto out; } else { err(1, "getline"); } } if ((len > 0) && (s[len - 1] == '\n')) { s[--len] = '\0'; } set_clipboard_func(s); status = EXIT_SUCCESS; out: free(s); exit(status); }