summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <curtis.mcenroe@adgear.com>2017-01-06 11:49:29 -0500
committerJune McEnroe <curtis.mcenroe@adgear.com>2017-01-06 11:55:02 -0500
commitee442870809ebfd9eefd8868314cafa5c001d925 (patch)
tree74902c85cc5e6964a94281e6e90a138e419e4d24
parentAdd custom keyboard layout for macOS (diff)
downloadsrc-ee442870809ebfd9eefd8868314cafa5c001d925.tar.gz
src-ee442870809ebfd9eefd8868314cafa5c001d925.zip
Implement pbcopy and pbpaste in C
Ted Unangst broke my netcat implementation of pbpaste with this commit:
<https://github.com/openbsd/src/commit/bb978d8>, which, when /dev/null
is attached to stdin, causes nc to exit and never read from the socket.

Turns out the core functionality of netcat can be implemented in about
50 lines of C.
-rwxr-xr-x.bin/pbcopy1
-rwxr-xr-x.bin/pbcopy.c52
-rwxr-xr-x.bin/pbpaste1
-rwxr-xr-xinstall.sh3
4 files changed, 53 insertions, 4 deletions
diff --git a/.bin/pbcopy b/.bin/pbcopy
deleted file mode 100755
index 925e098e..00000000
--- a/.bin/pbcopy
+++ /dev/null
@@ -1 +0,0 @@
-exec nc localhost 7062 > /dev/null
diff --git a/.bin/pbcopy.c b/.bin/pbcopy.c
new file mode 100755
index 00000000..37c334ca
--- /dev/null
+++ b/.bin/pbcopy.c
@@ -0,0 +1,52 @@
+#if 0
+cc -Wall -Wextra -pedantic $@ -o $(dirname $0)/pbcopy $0 && \
+exec cc -Wall -Wextra -pedantic -DPBPASTE $@ -o $(dirname $0)/pbpaste $0
+#endif
+
+#include <arpa/inet.h>
+#include <err.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+int main() {
+    int error;
+
+    int client = socket(PF_INET, SOCK_STREAM, 0);
+    if (client < 0) err(EX_OSERR, "socket");
+
+    struct sockaddr_in addr = {
+        .sin_family = AF_INET,
+        .sin_port = htons(7062),
+        .sin_addr = { .s_addr = htonl(0x7f000001) },
+    };
+
+    error = connect(client, (struct sockaddr *)&addr, sizeof(addr));
+    if (error) err(EX_OSERR, "connect");
+
+#ifdef PBPASTE
+    int fdIn = client;
+    int fdOut = STDOUT_FILENO;
+    error = shutdown(client, SHUT_WR);
+    if (error) err(EX_OSERR, "shutdown");
+#else
+    int fdIn = STDIN_FILENO;
+    int fdOut = client;
+#endif
+
+    char readBuf[4096];
+    ssize_t readLen;
+    while (0 < (readLen = read(fdIn, readBuf, sizeof(readBuf)))) {
+        char *writeBuf = readBuf;
+        ssize_t writeLen;
+        while (0 < (writeLen = write(fdOut, writeBuf, readLen))) {
+            writeBuf += writeLen;
+            readLen -= writeLen;
+        }
+        if (writeLen < 0) err(EX_IOERR, "write");
+    }
+    if (readLen < 0) err(EX_IOERR, "read");
+
+    return 0;
+}
diff --git a/.bin/pbpaste b/.bin/pbpaste
deleted file mode 100755
index 9ce6f6dd..00000000
--- a/.bin/pbpaste
+++ /dev/null
@@ -1 +0,0 @@
-exec nc localhost 7062 < /dev/null
diff --git a/install.sh b/install.sh
index eba39dbe..3c0c5ed3 100755
--- a/install.sh
+++ b/install.sh
@@ -28,9 +28,8 @@ fi
 
 link .bin/jrp.c
 link .bin/manpager
-link .bin/pbcopy
+link .bin/pbcopy.c
 link .bin/pbd.c
-link .bin/pbpaste
 link .bin/xx.c
 link .config/git/config
 link .config/git/ignore