My guestbook setup

2024-07-06

My guestbook is a sheepy program written in C running as CGI.

The `guestbook` program is stored in the `cgi` directory with a template.

When `cgi/guestbook` runs, an input is requested and when the input is received, it is stored in `guestbook.gmi`.

- Template `guestbookTemplate.gmi`:

# Guestbook

=> cgi/guestbook Add message to guestbook (gemini only)
=> / Home


- `guestbook.c`:

#! /usr/bin/env sheepy
/* or direct path to sheepy: #! /usr/local/bin/sheepy */

/* Libsheepy documentation: https://spartatek.se/libsheepy/ */
#include "libsheepyObject.h"
#include "shpPackages/short/short.h"

#define dir "/var/geminiRoot/"

int main(int ARGC, char** ARGV) {

  initLibsheepy(ARGV[0]);
  setLogMode(LOG_PROG);
  setLogSymbols(LOG_CONCISE);
  keepAnsiColorsInLog(no);
  disableLibsheepyErrorLogs;

  var pathInfo = getenv("PATH_INFO");
  var query    = getenv("QUERY_STRING");

  // Ask for input when query is empty
  if (isEmptyG(query)) {
    puts("10 Write your signature on last line:\r\n");
    ret 0;
  }

  // debug
  //puts("20 text/gemini\r\n");
  //puts(pathInfo);
  cleanCharP(path)    = expandHomeG(dir);
  // Add > on last non empty line
  // Split query and store it an array
  cleanAllocateSmallString(q);
  setValO(q, query);
  cleanSmallArrayP(a) = splitG(q, '\n');
  compactG(a);
  setNFreeG(a, -1, prependG($(a, -1), "> "));
  // Add date on first line
  prependNFreeG(a, getCurrentDateYMD());
  // New line between posts
  pushG(a, "\n");
  cleanCharP(post) = joinSG(a, '\n');
  // Save query in questbook, most recent on top
  // Template is top most
  u64 bufsz = 0;
  cleanCharP(templatePath) = catS(path, "cgi/guestbookTemplate.gmi");
  cleanCharP(rawbookPath)  = catS(path, "cgi/guestbook.gmi");
  u64 templateSz = 0;
  u64 postSz     = strlen(post);
  u64 rawbookSz  = 0;
  if (isPath(templatePath)) templateSz = fileSize(templatePath);
  if (isPath(rawbookPath))  rawbookSz = fileSize(rawbookPath);
  bufsz = templateSz + postSz + rawbookSz +1;
  cleanCharP(buf) = malloc(bufsz);
  if (!buf) ret 1;
  buf[bufsz-1] = 0;
  pError(bReadFile(templatePath, buf));
  memcpy(buf+templateSz, post, postSz);
  if (rawbookSz) pError(bReadFile(rawbookPath, buf+templateSz+postSz));
  cleanCharP(guestbookPath) = catS(path, "guestbook.gmi");
  // Update /guestbook.gmi
  writeFileG(buf, guestbookPath);
  // Update rawbook (without template)
  writeFileG(buf+templateSz, rawbookPath);

  // Redirect to guestbook
  puts("30 /guestbook.gmi\r\n");

  ret 0;
}
// vim: set expandtab ts=2 sw=2: