diff options
| author | Mitchell Riedstra <mitch@riedstra.dev> | 2024-01-02 17:38:12 -0500 |
|---|---|---|
| committer | Mitchell Riedstra <mitch@riedstra.dev> | 2024-01-02 17:38:12 -0500 |
| commit | 3bab6beb965b4c82aeb9a6775176ba6481f4dcfc (patch) | |
| tree | 0a3eb83cd4254f9851e135e327525b69cd1fe786 | |
| parent | a43600011a3ee977a10fdc863e5b79c272a7b5bd (diff) | |
| download | pm-3bab6beb965b4c82aeb9a6775176ba6481f4dcfc.tar.gz pm-3bab6beb965b4c82aeb9a6775176ba6481f4dcfc.tar.xz | |
Add support for MacOS
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | compat/reallocarray.c | 45 | ||||
| -rw-r--r-- | compat/strtonum.c | 65 | ||||
| -rwxr-xr-x | pm | 85 | ||||
| -rw-r--r-- | pm-fmtdb.c | 4 | ||||
| -rw-r--r-- | pm-genid.c | 95 | ||||
| -rw-r--r-- | readme.md | 6 |
8 files changed, 252 insertions, 56 deletions
@@ -1,2 +1,3 @@ ses.vim /pm-fmtdb +/pm-genid @@ -3,11 +3,12 @@ PREFIX ?= /usr/local CC ?= cc CFLAGS ?= -D_DEFAULT_SOURCE -std=c99 -pedantic -Wall -O2 -s -all: pm-fmtdb +all: pm-fmtdb pm-genid -install: pm-fmtdb +install: pm-fmtdb pm-genid install -m 755 pm-fmtdb $(PREFIX)/bin/pm-fmtdb + install -m 755 pm-genid $(PREFIX)/bin/pm-genid install -m 755 pm $(PREFIX)/bin/pm clean: - rm -f pm-fmtdb + rm -f pm-fmtdb pm-genid diff --git a/compat/reallocarray.c b/compat/reallocarray.c new file mode 100644 index 0000000..bb6921e --- /dev/null +++ b/compat/reallocarray.c @@ -0,0 +1,45 @@ +/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */ +/* + * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/stdlib/reallocarray.c */ + +#ifndef HAVE_REALLOCARRAY + +#include <sys/types.h> +#include <errno.h> +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +#include <stdlib.h> + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void * +reallocarray(void *optr, size_t nmemb, size_t size) +{ + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && SIZE_MAX / nmemb < size) { + errno = ENOMEM; + return NULL; + } + return realloc(optr, size * nmemb); +} +#endif /* HAVE_REALLOCARRAY */ diff --git a/compat/strtonum.c b/compat/strtonum.c new file mode 100644 index 0000000..fdfc72a --- /dev/null +++ b/compat/strtonum.c @@ -0,0 +1,65 @@ +/* $OpenBSD: strtonum.c,v 1.8 2015/09/13 08:31:48 guenther Exp $ */ + +/* + * Copyright (c) 2004 Ted Unangst and Todd Miller + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <errno.h> +#include <limits.h> +#include <stdlib.h> + +#define INVALID 1 +#define TOOSMALL 2 +#define TOOLARGE 3 + +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp) +{ + long long ll = 0; + int error = 0; + char *ep; + struct errval { + const char *errstr; + int err; + } ev[4] = { + { NULL, 0 }, + { "invalid", EINVAL }, + { "too small", ERANGE }, + { "too large", ERANGE }, + }; + + ev[0].err = errno; + errno = 0; + if (minval > maxval) { + error = INVALID; + } else { + ll = strtoll(numstr, &ep, 10); + if (numstr == ep || *ep != '\0') + error = INVALID; + else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) + error = TOOSMALL; + else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) + error = TOOLARGE; + } + if (errstrp != NULL) + *errstrp = ev[error].errstr; + errno = ev[error].err; + if (error) + ll = 0; + + return (ll); +} @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2023 Mitchell Riedstra +# Copyright (c) 2024 Mitchell Riedstra # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -13,7 +13,7 @@ # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. set -e -PASTE_MANAGER_FILE=~/.pastes +PASTE_MANAGER_FILE="${PASTE_MANAGER_FILE:-$HOME/.pastes}" PASTE_MANAGER_LINES="${PASTE_MANAGER_LINES:-30}" PASTE_MANAGER_X_SELECTION="${PASTE_MANAGER_X_SELECTION:-clipboard}" @@ -21,19 +21,20 @@ PASTE_MANAGER_X_SELECTION="${PASTE_MANAGER_X_SELECTION:-clipboard}" # the only option called elsewhere is `-p` _menu="dmenu -l $PASTE_MANAGER_LINES -i" +case $(uname) in + Darwin) _menu="choose -m -s 16 -f Monaco -n $PASTE_MANAGER_LINES -w 85" ;; + *) ;; +esac + genid() { + if [ -x "$(command -v pm-genid)" ] ; then + pm-genid + return + fi { dd if=/dev/urandom 2>/dev/null | tr -C -d 'a-zA-Z0-9'; echo; } \ | fold -w 8 | sed 1q } -getFifo() { - _p="$(mktemp)" - rm -f "$_p" - sleep 0.1 - mkfifo "$_p" - echo "$_p" -} - _clip() { case $(uname) in Darwin) @@ -48,23 +49,26 @@ esac insert() { exec <&- - $_menu -p "Enter name: " > "$_fifo" & - name="$(tr -d '\n' < "$_fifo")" + name="$(printf "_\n" | $_menu -p "Enter name: ")" + name="$(echo "$name" | tr -d '\n')" [ -z "$name" ] && exit 1 - $_menu -p "Enter content: " > "$_fifo" & - content="$(tr -d '\n' < "$_fifo")" + content="$(printf "_\n" | $_menu -p "Enter content: ")" + content="$(echo "$content" | tr -d '\n')" [ -z "$content" ] && exit 1 + id="$(genid)" + [ -z "$id" ] && { echo "ID empty" ; exit 1; } + printf "%s::%s::%s::%s::%s\n" \ - "$(genid)" "$(date +%s)" "$(date +%s)" "$name" "$content" \ + "$id" "$(date +%s)" "$(date +%s)" "$name" "$content" \ >> "$PASTE_MANAGER_FILE" } sel() { pm-fmtdb -f "$PASTE_MANAGER_FILE" \ | $_menu -p "$@" \ - | sed -re 's/^ID: ([^ ]*).*$/\1/' + | sed -r -e 's/^ID: ([^ ]*).*$/\1/' } selectName() { @@ -90,40 +94,28 @@ selectContent() { } copy() { - sel "Will copy content" > "$_fifo" & - read -r id < "$_fifo" - selectContent "$id" \ - | _clip + selectContent "$(sel "Will copy content")" | _clip } copyName() { - sel "Will copy entry name" > "$_fifo" & - read -r id < "$_fifo" - selectName "$id" \ - | _clip + selectName "$(sel "Will copy entry name")" | _clip } _type() { - sel "Will type content" > "$_fifo" & - read -r id < "$_fifo" - selectContent "$id" \ + selectContent "$(sel "Will type content")" \ | xdotool type --delay 1ms --clearmodifiers --file - } typeName() { - sel "Will type entry name" > "$_fifo" & - read -r id < "$_fifo" - selectName "$id" \ + selectName "$(sel "Will type entry name")" \ | xdotool type --delay 1ms --clearmodifiers --file - } rename() { - sel "Item to rename" > "$_fifo" & - read -r id < "$_fifo" + id="$(sel "Item to rename")" item="$(grep "^$id" "$PASTE_MANAGER_FILE" | pm-fmtdb -f - )" name="$(selectName "$id")" - $_menu -p "Currently: ( $name ) New Name" > "$_fifo" & - read -r name < "$_fifo" + name="$($_menu -p "Currently: ( $name ) New Name")" cp "$PASTE_MANAGER_FILE" "$PASTE_MANAGER_FILE".bak awk -F:: -v id="$id" -v name="$name" ' BEGIN { OFS="::"; } @@ -138,12 +130,10 @@ rename() { } update() { - sel "Item to update" > "$_fifo" & - read -r id < "$_fifo" + id="$(sel "Item to update")" item="$(grep "^$id" "$PASTE_MANAGER_FILE" | pm-fmtdb -f - )" output="$(selectContent "$id")" - $_menu -p "Currently: ( $output ) New Content" > "$_fifo" & - read -r content < "$_fifo" + content="$(printf "_\n" | $_menu -p "Currently: ( $output ) New Content")" cp "$PASTE_MANAGER_FILE" "$PASTE_MANAGER_FILE".bak awk -F:: -v id="$id" -v content="$content" ' BEGIN { OFS="::"; } @@ -158,13 +148,10 @@ update() { } delete() { - sel "Item to delete" > "$_fifo" & - read -r id < "$_fifo" + id="$(sel "Item to delete")" + [ -z "$id" ] && exit 1 item="$(grep "^$id" "$PASTE_MANAGER_FILE" | pm-fmtdb -f - )" - echo Item: "$item"' -yes -no' | $_menu -p "Are you sure?" > "$_fifo" & - read -r resp < "$_fifo" + resp="$(printf 'Item: "%s"\nyes\nno\n' "$item" | $_menu -p "Are you sure?")" if [ "$resp" = "yes" ] ; then cp "$PASTE_MANAGER_FILE" "$PASTE_MANAGER_FILE".bak sed '/^'"$id"/d < "$PASTE_MANAGER_FILE".bak > "$PASTE_MANAGER_FILE" @@ -181,11 +168,7 @@ rename update' menu() { - echo "$actions" | $_menu -p "Command:" \ - | { - read -r action; - runAction "$action"; - } + runAction "$(echo "$actions" | $_menu -p "Command:")" } runAction() { @@ -219,9 +202,5 @@ EOF exit 1 } -_fifo="$(getFifo)" - action="${1:-menu}" runAction "$action" - -rm -f "$_fifo" @@ -26,6 +26,10 @@ #include <fcntl.h> #include <unistd.h> +#if __APPLE__ + #include "compat/reallocarray.c" +#endif + #define TIME_FMT_CREATED "%H:%M:%S %m.%d.%y" #define TIME_FMT_UPDATED "%m.%d.%y" diff --git a/pm-genid.c b/pm-genid.c new file mode 100644 index 0000000..5a481ce --- /dev/null +++ b/pm-genid.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2024 Mitchell Riedstra + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Since `tr` on MacOS cannot handle the binary stream. + * + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> + +#if __linux__ + #include "compat/strtonum.c" +#endif + +#define BUF_SIZE 64 +#define MAX_OUT_CHARS 65534 + +void +help() { + puts("genid [-d <rand device>] [-n <numchars]"); + exit(1); +} + +int +main(int argc, char **argv) +{ + const char *rdev = "/dev/urandom"; + int chars = 8; + char **a = argv+1; + int fd, n; + char c; + int written = 0; + + for (;*a;a++) { + if (strcmp(*a, "-d") == 0 && *(++a)) { + rdev = *a; + } else if (strcmp(*a, "-n") == 0 && *(++a)) { + const char *errstr; + chars = (int)strtonum(*a, 1, MAX_OUT_CHARS, &errstr); + if (errstr != NULL) { + printf("strtonum: %s\n", errstr); + help(); + } + } else { + if (*a) + printf("Unknown option: '%s'\n", *a); + + help(); + } + } + + fd = open(rdev, O_RDONLY); + if (fd == -1) { + perror("opening random device"); + exit(1); + } + + char buf[BUF_SIZE]; + for (int i=0; written<chars && i<1000; i++) { + n = read(fd, &buf, BUF_SIZE-1); + if (n == -1) { + perror("read"); + exit(1); + } + + for (int j = 0; j<n && j<BUF_SIZE && written<chars; j++) { + c = buf[j]; + if ( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') + ) { + written++; + putc(c, stdout); + } + } + } + + puts(""); + close(fd); +} @@ -56,6 +56,12 @@ Edit the source code for further tweaks. The one people may have the most interest in is the format sent to `dmenu`, that's controlled via the small c program 'pm-fmtdb' near the top of the file. + +### MacOS + +You'll need a [menu](https://github.com/chipsenkbeil/choose), and you'll +probably want a [hotkey daemon](https://github.com/koekeishiya/skhd). + ## Bugs Probably. This was written in just a few hours. Email me if you find any, I'll |
