--- /dev/null
+// SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "aa.h"
+#include "request.h"
+
+// Read in lines from standard input, parse them as path info, and then
+// reserialize them to standard output.
+int cmd_main(int argc, [[maybe_unused]] const char* argv[argc+1]) {
+ char* lineptr[1] = { nullptr };
+ size_t linelen[1] = { 0 };
+ while (true) {
+ ssize_t readlen = getline(lineptr, linelen, stdin);
+ if (!feof(stdin) && readlen > 0) {
+ char* line = nullptr;
+ char* reline = nullptr;
+ bool empty = false;
+ if (readlen == 1) {
+ line = "";
+ empty = true;
+ } else {
+ line = strndup(lineptr[0], readlen - 1);
+ if (!line) {
+ free(lineptr[0]);
+ fprintf(stderr, "Error: Failed to allocate string for line.\n");
+ return EXIT_FAILURE;
+ }
+ }
+ cgirls_req req = cgirls_path2req(line);
+ if (!empty) {
+ free(line);
+ }
+ line = cgirls_req2path(req);
+ cgirls_freereq(req);
+ if (!line) {
+ free(lineptr[0]);
+ fprintf(stderr, "Error: Failed to allocate string for path.\n");
+ return EXIT_FAILURE;
+ }
+ req = cgirls_path2req(line);
+ reline = cgirls_req2path(req);
+ cgirls_freereq(req);
+ if (!reline) {
+ free(lineptr[0]);
+ free(line);
+ fprintf(stderr, "Error: Failed to allocate another string for path.\n");
+ return EXIT_FAILURE;
+ }
+ if (strcmp(line, reline) != 0) {
+ free(lineptr[0]);
+ fprintf(stderr, "Error: Path normalization was not idempotent for path <%s> (got <%s>).\n", line, reline);
+ free(line);
+ free(reline);
+ return EXIT_FAILURE;
+ }
+ free(reline);
+ fprintf(stdout, "%s\n", line);
+ free(line);
+ } else if (!feof(stdin)) {
+ free(lineptr[0]);
+ fprintf(stderr, "Error: Got an error from trying to read from file.\n");
+ return EXIT_FAILURE;
+ } else if (readlen > 0) {
+ free(lineptr[0]);
+ fprintf(stderr, "Error: Final line in file was not blank.\n");
+ return EXIT_FAILURE;
+ } else {
+ free(lineptr[0]);
+ return EXIT_SUCCESS;
+ }
+ }
+}