Add first stab at tagging
authorChip Black <bytex64@bytex64.net>
Tue, 23 Nov 2010 09:36:12 +0000 (03:36 -0600)
committerChip Black <bytex64@bytex64.net>
Tue, 23 Nov 2010 09:36:12 +0000 (03:36 -0600)
config.h
tags.c [new file with mode: 0644]
tags.h [new file with mode: 0644]

index c3b8610..1b5e49d 100644 (file)
--- a/config.h
+++ b/config.h
@@ -2,5 +2,6 @@
 #define _CONFIG_H
 
 #define DATA_PATH "data"
+#define TAGS_PATH "tags"
 
 #endif //_CONFIG_H
diff --git a/tags.c b/tags.c
new file mode 100644 (file)
index 0000000..d5cc48a
--- /dev/null
+++ b/tags.c
@@ -0,0 +1,83 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include "tags.h"
+#include "config.h"
+
+#define MAX_TAG_LENGTH 64
+#define MAX_TAGS 1024
+
+#define TAG_CHAR(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '_')
+
+int tag_scan(const char *author, const char *data, int len, uint64_t record) {
+       char *taglist[MAX_TAGS];
+       int n_tags = 0;
+       int i, j;
+
+       for (i = 0; i < len; i++) {
+tag_scan_start:
+               if (data[i] == '#') {
+                       if (n_tags == MAX_TAGS) {
+                               fprintf(stderr, "Too many tags in message");
+                               continue;
+                       }
+                       int start = ++i;
+                       while (i < len && TAG_CHAR(data[i]) && (i - start < MAX_TAG_LENGTH)) {
+                               i++;
+                       }
+                       if (start - i == 0) continue;
+                       char *tag = calloc(1, MAX_TAG_LENGTH + 1);
+                       memcpy(tag, &data[start], i - start);
+                       for (j = 0; j < n_tags; j++) {
+                               if (!strncmp(tag, taglist[j], MAX_TAG_LENGTH)) {
+                                       // We already have this tag.  Start over.
+                                       free(tag);
+                                       goto tag_scan_start;
+                               }
+                       }
+                       taglist[n_tags] = tag;
+                       n_tags++;
+                       // We goto here so i doesn't get incremented
+                       goto tag_scan_start;
+               }
+       }
+
+       for (i = 0; i < n_tags; i++) {
+               tag_add(author, taglist[i], record);
+               free(taglist[i]);
+       }
+}
+
+int tag_add(const char *author, const char *tag, uint64_t record) {
+       char filename[512];
+       struct tag t;
+
+       memset(t.author, 0, 32);
+       strncpy(t.author, author, 32);
+       t.record = record;
+
+       snprintf(filename, 512, "%s/%s", TAGS_PATH, tag);
+       int tag_fd = open(filename, O_WRONLY | O_APPEND | O_CREAT, 0600);
+       flock(tag_fd, LOCK_EX);
+       if (tag_fd == -1) {
+               perror("Could not open tag file");
+               return 0;
+       }
+       int n = write(tag_fd, &t, sizeof(struct tag));
+       if (n < sizeof(struct tag)) {
+               perror("Could not write new tag");
+               return 0;
+       }
+       flock(tag_fd, LOCK_UN);
+       close(tag_fd);
+
+       return 1;
+}
+
+int tag_list(const char *tag, int start, int count) {
+}
diff --git a/tags.h b/tags.h
new file mode 100644 (file)
index 0000000..3247caa
--- /dev/null
+++ b/tags.h
@@ -0,0 +1,15 @@
+#ifndef _TAGS_H
+#define _TAGS_H
+
+#include <stdint.h>
+
+struct tag {
+       char author[32];
+       uint64_t record;
+};
+
+int tag_scan(const char *, const char *, int, uint64_t);
+int tag_add(const char *, const char *, uint64_t);
+int tag_list(const char *, int, int);
+
+#endif //_TAGS_H