summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <programble@gmail.com>2016-09-17 00:21:04 -0400
committerJune McEnroe <programble@gmail.com>2016-09-17 00:21:04 -0400
commit9e5151366f57f8dfe6406da29a606eb52d794b73 (patch)
tree458473f2aa2cf021981cc3d9e2262eeb27f63cef
parentExecute Homebrew SSH for tux iTerm profile (diff)
downloadsrc-9e5151366f57f8dfe6406da29a606eb52d794b73.tar.gz
src-9e5151366f57f8dfe6406da29a606eb52d794b73.zip
Add initial pbd implementation
Error handling in C is tedious.
-rwxr-xr-x.bin/pbd.c71
-rwxr-xr-xinstall.sh1
2 files changed, 72 insertions, 0 deletions
diff --git a/.bin/pbd.c b/.bin/pbd.c
new file mode 100755
index 00000000..713800d4
--- /dev/null
+++ b/.bin/pbd.c
@@ -0,0 +1,71 @@
+#if 0
+exec clang -Weverything $@ -o $(dirname $0)/pbd $0
+#endif
+
+#include <arpa/inet.h>
+#include <err.h>
+#include <netinet/in.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+int main() {
+    int server = socket(PF_INET, SOCK_STREAM, 0);
+    if (server < 0) err(EX_OSERR, "socket");
+
+    struct sockaddr_in addr = {
+        .sin_family = AF_INET,
+        .sin_port = htons(7062),
+        .sin_addr = { .s_addr = htonl(0x7f000001) },
+    };
+
+    if (bind(server, (struct sockaddr *) &addr, sizeof(addr)) < 0)
+        err(EX_OSERR, "bind");
+
+    if (listen(server, 1) < 0)
+        err(EX_OSERR, "listen");
+
+    for (;;) {
+        int client = accept(server, NULL, NULL);
+        if (client < 0) err(EX_OSERR, "accept");
+
+        pid_t pid_paste = fork();
+        if (pid_paste < 0) err(EX_OSERR, "fork");
+
+        if (pid_paste) {
+            if (waitpid(pid_paste, NULL, 0) < 0)
+                warn("waitpid");
+            // TODO: Check child status.
+        } else {
+            if (dup2(client, STDOUT_FILENO) < 0)
+                err(EX_OSERR, "dup2");
+            if (execlp("pbpaste", "pbpaste") < 0)
+                err(EX_OSERR, "execlp");
+        }
+
+        uint8_t x;
+        ssize_t peek = recv(client, &x, 1, MSG_PEEK);
+        if (peek < 0) err(EX_IOERR, "recv");
+
+        if (peek) {
+            pid_t pid_copy = fork();
+            if (pid_copy < 0) err(EX_OSERR, "fork");
+
+            if (pid_copy) {
+                if (waitpid(pid_copy, NULL, 0) < 0)
+                    warn("waitpid");
+                // TODO: Check child status.
+            } else {
+                if (dup2(client, STDIN_FILENO) < 0)
+                    err(EX_OSERR, "dup2");
+                if (execlp("pbcopy", "pbcopy") < 0)
+                    err(EX_OSERR, "execlp");
+            }
+        }
+
+        if (close(client) < 0) warn("close");
+    }
+}
diff --git a/install.sh b/install.sh
index dd18fe28..54376f8d 100755
--- a/install.sh
+++ b/install.sh
@@ -22,6 +22,7 @@ link() {
 }
 
 link .bin/manpager
+link .bin/pbd.c
 link .bin/xx.c
 link .config/git/config
 link .config/git/ignore