d5cc48a385c61b377e39b407b1182caac8c96539
[blerg.git] / tags.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <fcntl.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <sys/file.h>
9 #include "tags.h"
10 #include "config.h"
11
12 #define MAX_TAG_LENGTH 64
13 #define MAX_TAGS 1024
14
15 #define TAG_CHAR(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '_')
16
17 int tag_scan(const char *author, const char *data, int len, uint64_t record) {
18         char *taglist[MAX_TAGS];
19         int n_tags = 0;
20         int i, j;
21
22         for (i = 0; i < len; i++) {
23 tag_scan_start:
24                 if (data[i] == '#') {
25                         if (n_tags == MAX_TAGS) {
26                                 fprintf(stderr, "Too many tags in message");
27                                 continue;
28                         }
29                         int start = ++i;
30                         while (i < len && TAG_CHAR(data[i]) && (i - start < MAX_TAG_LENGTH)) {
31                                 i++;
32                         }
33                         if (start - i == 0) continue;
34                         char *tag = calloc(1, MAX_TAG_LENGTH + 1);
35                         memcpy(tag, &data[start], i - start);
36                         for (j = 0; j < n_tags; j++) {
37                                 if (!strncmp(tag, taglist[j], MAX_TAG_LENGTH)) {
38                                         // We already have this tag.  Start over.
39                                         free(tag);
40                                         goto tag_scan_start;
41                                 }
42                         }
43                         taglist[n_tags] = tag;
44                         n_tags++;
45                         // We goto here so i doesn't get incremented
46                         goto tag_scan_start;
47                 }
48         }
49
50         for (i = 0; i < n_tags; i++) {
51                 tag_add(author, taglist[i], record);
52                 free(taglist[i]);
53         }
54 }
55
56 int tag_add(const char *author, const char *tag, uint64_t record) {
57         char filename[512];
58         struct tag t;
59
60         memset(t.author, 0, 32);
61         strncpy(t.author, author, 32);
62         t.record = record;
63
64         snprintf(filename, 512, "%s/%s", TAGS_PATH, tag);
65         int tag_fd = open(filename, O_WRONLY | O_APPEND | O_CREAT, 0600);
66         flock(tag_fd, LOCK_EX);
67         if (tag_fd == -1) {
68                 perror("Could not open tag file");
69                 return 0;
70         }
71         int n = write(tag_fd, &t, sizeof(struct tag));
72         if (n < sizeof(struct tag)) {
73                 perror("Could not write new tag");
74                 return 0;
75         }
76         flock(tag_fd, LOCK_UN);
77         close(tag_fd);
78
79         return 1;
80 }
81
82 int tag_list(const char *tag, int start, int count) {
83 }