A bin/chat0/Makefile => bin/chat0/Makefile +15 -0
@@ 0,0 1,15 @@
+all: index.gmi post postuser
+
+CFLAGS=-O3 -Wall -Wextra -pedantic -Wpedantic
+
+index.gmi: view.c config.h
+ cc $(CFLAGS) view.c -o index.gmi
+
+post: post.c config.h
+ cc $(CFLAGS) post.c -o post
+
+postuser: postuser.c config.h
+ cc $(CFLAGS) postuser.c -o postuser
+
+clean:
+ rm -f index.gmi post postuser
A bin/chat0/TODO => bin/chat0/TODO +3 -0
@@ 0,0 1,3 @@
+[ ] Implement spam protection
+[ ] Implement multi line support
+[ ] add message ids
A bin/chat0/config.h => bin/chat0/config.h +4 -0
@@ 0,0 1,4 @@
+#pragma once
+
+#define CHAT_NUM "2"
+#define BUFF_SIZE 600
D bin/chat0/index.gmi => bin/chat0/index.gmi +0 -14
@@ 1,14 0,0 @@
-#! /bin/dash
-
-echo "20 text/gemini\r\n"
-echo "# Chatroom 0"
-echo "=> postuser post"
-echo "=> post post anonymously"
-echo "=> $GEMINI_URL refresh"
-printf "\n"
-
-echo ---
-echo "\`\`\` Messages"
-tac message_log | awk '$1 != '\n' {print $0}'
-echo "\`\`\`"
-echo ---
D bin/chat0/post => bin/chat0/post +0 -24
@@ 1,24 0,0 @@
-#! /bin/bash
-
-chatNum=0
-
-if [ -z "$QUERY_STRING" ]; then
- echo -e "10 Message\r\n"
-fi
-
-user=$(echo $PATH_INFO | cut -d '/' -f 2)
-
-if [ -z "$user" ]; then
- user="anon"
-fi
-
-nstr=$(echo $QUERY_STRING | sed 's/\(%0A\|
\)/ /g' | sed 's/%/\\x/g')
-nuser=$(echo ${user//[!A-z]/})
-
-if [ $(cat last_message) != $nstr ]; then
- printf "($(date "+%Y/%m/%d %R %Z")) $(echo $nuser: $nstr | awk '{printf "%9s %s\n", $1, $2}')\n" >> message_log
- echo $nstr > last_message
- echo -e "30 /bin/chat$chatNum\r\n"
-else
- echo -e "40 Message failed! Reason: Spam protection\r\n"
-fi
A bin/chat0/post.c => bin/chat0/post.c +95 -0
@@ 0,0 1,95 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "config.h"
+
+char *
+removeExtraChars(char user[9])
+{
+ static char nUser[9];
+ unsigned int nUserLen = 0;
+
+ for (unsigned int i = 0; i < 9; i++) {
+ if ((user[i] >= 'a' && user[i] <= 'z') || (user[i] >= 'A' && user[i] <= 'Z') || (user[i] >= '0' && user[i] <= '9'))
+ nUser[nUserLen++] = user[i];
+ else if (user[i] == '\0')
+ break;
+ }
+ return nUser;
+}
+
+void
+convert(char *str, char **nstr)
+{ /* free ret after */
+ size_t strsize = strlen(str), retsize = 0;
+ char *ret = malloc(strsize);
+ char tmp[2];
+
+ for (unsigned int i = 0; i < strsize; i++) {
+ if (str[i] == '%') {
+ ret = realloc(ret, ++retsize);
+ tmp[0] = str[++i];
+ tmp[1] = str[++i];
+ sscanf(tmp, "%x", (unsigned int *)&ret[retsize - 1]);
+ } else ret[retsize++] = str[i];
+ }
+ ret[retsize] = '\0';
+ *nstr = ret;
+}
+
+void
+getTime(char **timestr)
+{
+ time_t t = time(NULL);
+ struct tm tm = *localtime(&t);
+ sprintf(*timestr, "(%d/%02d/%02d %02d:%02d)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min);
+}
+
+int
+main()
+{
+ /* variables */
+ char *PATH_INFO = getenv("PATH_INFO");
+ char *QUERY_STRING = getenv("QUERY_STRING");
+ char user[9];
+ FILE *ml;
+
+ /* get username */
+ if (PATH_INFO == NULL || !strcmp(PATH_INFO, ""))
+ memcpy(user, "anon\0", 5);
+ else {
+ if (strlen(PATH_INFO) > 9) {
+ puts("40 Message failed! Reason: Username must be below 9 characters\r");
+ exit(0);
+ } else memcpy(user, removeExtraChars(PATH_INFO), 9);
+ }
+
+ /* get input */
+ if (QUERY_STRING == NULL)
+ puts("10 Message\r");
+ if (QUERY_STRING == NULL)
+ exit(0);
+
+ /*
+ * write message to file
+ */
+ ml = fopen("message_log", "a");
+ /* get time */
+ char *timestr = malloc(19);
+ getTime(×tr);
+
+ /* replace % with \x */
+ char *message;
+ convert(QUERY_STRING, &message);
+
+ /* print to file */
+ fprintf(ml, "%s %8s: %s\n", timestr, user, message);
+ free(timestr);
+ free(message);
+ fclose(ml);
+
+ /* redirect back to messages */
+ puts("30 /bin/chat"CHAT_NUM"/\r");
+}
D bin/chat0/postuser => bin/chat0/postuser +0 -12
@@ 1,12 0,0 @@
-#! /bin/dash
-
-if [ -z $QUERY_STRING ]; then
- echo "10 Username\r\n"
-fi
-
-if [ ${#QUERY_STRING} -gt 9 ]; then
- echo "40 Message failed! Reason: Username must be below 9 characters\r\n"
- exit 0
-fi
-
-echo "30 post/$QUERY_STRING\r\n"
A bin/chat0/postuser.c => bin/chat0/postuser.c +11 -0
@@ 0,0 1,11 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+main()
+{
+ if (getenv("QUERY_STRING") == NULL)
+ puts("10 username \r");
+ printf("30 post/%s\r\n", getenv("QUERY_STRING"));
+}
A bin/chat0/view.c => bin/chat0/view.c +65 -0
@@ 0,0 1,65 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+
+char *
+fgetsr(char *str, unsigned int size, FILE *fp) /* fgets, reversed */
+{
+ /* Stop if we're at the beginning of the file */
+ if (ftell(fp) == 0)
+ return NULL;
+
+ unsigned int i;
+ for (i = 0; ftell(fp) != 0 && i < size; i++ ) {
+ fseek(fp, -1, SEEK_CUR);
+ str[i] = (char)fgetc(fp);
+
+ if (str[i] == '\n' && i != 0 ) {
+ break;
+ }
+
+ fseek(fp, -1, SEEK_CUR);
+ }
+ str[i] = '\0';
+ return str;
+}
+
+void
+reverseStr(char *start)
+{
+ size_t len = strlen(start);
+
+ for (char *end = &start[len - 1]; start < end; start++, end--) {
+ char tmp = start[0];
+ start[0] = end[0];
+ end[0] = tmp;
+ }
+}
+
+int
+main()
+{
+ /* open file and navigate to the end */
+ FILE *ml = fopen("message_log", "r"); /* message log */
+ fseek(ml, 0, SEEK_END);
+
+ /* write links */
+ puts("20 text/gemini\r");
+ puts("# Chatroom 0");
+ puts("=> postuser post");
+ puts("=> post post anonymously");
+ puts("=> /bin/chat"CHAT_NUM"/ refresh\n");
+
+ /* print file backwards */
+ char buff[BUFF_SIZE];
+ puts("---");
+ puts("``` messages");
+ while (fgetsr(buff, BUFF_SIZE, ml) != NULL) {
+ reverseStr(buff);
+ printf("%s", buff);
+ }
+ fclose(ml);
+ puts("```");
+ puts("---");
+}