summaryrefslogtreecommitdiff
path: root/src/fscomch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fscomch.c')
-rw-r--r--src/fscomch.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/fscomch.c b/src/fscomch.c
new file mode 100644
index 0000000..a9fc27b
--- /dev/null
+++ b/src/fscomch.c
@@ -0,0 +1,97 @@
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/stat.h>
+#include "fscomch.h"
+
+match_t init_match(char* uuid, FILE* streamIn, FILE* streamOut) {
+ match_t match;
+ match.uuid = uuid;
+ match.streamIn = streamIn;
+ match.streamOut = streamOut;
+ return match;
+}
+void destroy_match(match_t match) {
+ free(match.uuid);
+ fclose(match.streamIn);
+ fclose(match.streamOut);
+}
+FILE* try_lock_match() {
+ mkdir("/tmp/chess/", 0777);
+ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ int fd = open("/tmp/chess/match", O_RDONLY | O_CREAT | O_EXCL, mode);
+ if (fd == -1) {
+ return NULL;
+ }
+ return fdopen(fd, "r");
+}
+match_t await_match(FILE* matchFile, char* cancelToken) {
+ /* await match UUID */
+ char* uuid = calloc(37, sizeof(char));
+ while (cancelToken == NULL || *cancelToken) {
+ if (fgets(uuid, 37, matchFile) != NULL) {
+ break;
+ }
+ fseek(matchFile, 0, SEEK_SET);
+ struct timespec req;
+ req.tv_sec = 0;
+ req.tv_nsec = awaitMatchNs;
+ printf("sleeping\n");
+ nanosleep(&req, NULL);
+ }
+ /* connect to files created by joining player */
+ char aName[256];
+ char bName[256];
+ snprintf(aName, 256, "/tmp/chess/%s.a", uuid);
+ snprintf(bName, 256, "/tmp/chess/%s.b", uuid);
+ FILE* streamIn = fopen(aName, "r");
+ FILE* streamOut = fopen(bName, "w");
+ /* connection complete, delete the match file and the join lock */
+ remove("/tmp/chess/match");
+ remove("/tmp/chess/matchjoin");
+ return init_match(uuid, streamIn, streamOut);
+}
+match_t join_match() {
+ /* create a join lock so that no one else can join this match */
+ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ int fd = open("/tmp/chess/matchjoin", O_WRONLY | O_CREAT | O_EXCL, mode);
+ if (fd == -1) {
+ /* another process is in the process of joining this game */
+ match_t match;
+ return match;
+ }
+ /* this is definitely the only process joining the game
+ proceed to generate a uuid */
+ char* uuid = make_uuid();
+ /* make the .a and .b files based on the uuid */
+ char aName[256];
+ char bName[256];
+ snprintf(aName, 256, "/tmp/chess/%s.a", uuid);
+ snprintf(bName, 256, "/tmp/chess/%s.b", uuid);
+ FILE* streamIn = fopen(bName, "w+");
+ FILE* streamOut = fopen(aName, "w");
+ match_t match = init_match(uuid, streamIn, streamOut);
+ /* send uuid to the host */
+ FILE* matchFile = fopen("/tmp/chess/match", "a");
+ fputs(uuid, matchFile);
+ /* joining match complete, close the descriptor */
+ close(fd);
+ return match;
+}
+char* make_uuid() {
+ char sym[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f'};
+ char* out = calloc(37, sizeof(char));
+ srand(time(NULL));
+ for (int i = 0; i < 36; i++) {
+ if (i == 8 || i == 13 || i == 18 || i == 23) {
+ out[i] = '-';
+ }
+ else {
+ out[i] = sym[rand() % 16];
+ }
+ }
+ out[37] = '\0';
+ return out;
+}