summaryrefslogtreecommitdiff
path: root/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'data.c')
-rw-r--r--data.c130
1 files changed, 121 insertions, 9 deletions
diff --git a/data.c b/data.c
index f4cd6d6..d3045f4 100644
--- a/data.c
+++ b/data.c
@@ -9,6 +9,7 @@
9#include "xs_glob.h" 9#include "xs_glob.h"
10#include "xs_set.h" 10#include "xs_set.h"
11#include "xs_time.h" 11#include "xs_time.h"
12#include "xs_regex.h"
12 13
13#include "snac.h" 14#include "snac.h"
14 15
@@ -116,21 +117,33 @@ int srv_open(char *basedir, int auto_upgrade)
116 srv_debug(1, xs_dup("OpenBSD security disabled by admin")); 117 srv_debug(1, xs_dup("OpenBSD security disabled by admin"));
117 } 118 }
118 else { 119 else {
120 int smail = xs_type(xs_dict_get(srv_config, "disable_email_notifications")) != XSTYPE_TRUE;
121
119 srv_debug(1, xs_fmt("Calling unveil()")); 122 srv_debug(1, xs_fmt("Calling unveil()"));
120 unveil(basedir, "rwc"); 123 unveil(basedir, "rwc");
121 unveil("/tmp", "rwc"); 124 unveil("/tmp", "rwc");
122 unveil("/usr/sbin/sendmail", "x");
123 unveil("/etc/resolv.conf", "r"); 125 unveil("/etc/resolv.conf", "r");
124 unveil("/etc/hosts", "r"); 126 unveil("/etc/hosts", "r");
125 unveil("/etc/ssl/openssl.cnf", "r"); 127 unveil("/etc/ssl/openssl.cnf", "r");
126 unveil("/etc/ssl/cert.pem", "r"); 128 unveil("/etc/ssl/cert.pem", "r");
127 unveil("/usr/share/zoneinfo", "r"); 129 unveil("/usr/share/zoneinfo", "r");
130
131 if (smail)
132 unveil("/usr/sbin/sendmail", "x");
133
128 unveil(NULL, NULL); 134 unveil(NULL, NULL);
129 srv_debug(1, xs_fmt("Calling pledge()")); 135 srv_debug(1, xs_fmt("Calling pledge()"));
130 pledge("stdio rpath wpath cpath flock inet proc exec dns fattr", NULL); 136
137 if (smail)
138 pledge("stdio rpath wpath cpath flock inet proc exec dns fattr", NULL);
139 else
140 pledge("stdio rpath wpath cpath flock inet proc dns fattr", NULL);
131 } 141 }
132#endif /* __OpenBSD__ */ 142#endif /* __OpenBSD__ */
133 143
144 /* read (and drop) emojis.json, possibly creating it */
145 xs_free(emojis());
146
134 return ret; 147 return ret;
135} 148}
136 149
@@ -393,7 +406,7 @@ int index_del_md5(const char *fn, const char *md5)
393 fclose(f); 406 fclose(f);
394 } 407 }
395 else 408 else
396 status = 500; 409 status = 410;
397 410
398 pthread_mutex_unlock(&data_mutex); 411 pthread_mutex_unlock(&data_mutex);
399 412
@@ -796,6 +809,30 @@ double object_ctime(const char *id)
796} 809}
797 810
798 811
812double object_mtime_by_md5(const char *md5)
813{
814 xs *fn = _object_fn_by_md5(md5, "object_mtime_by_md5");
815 return mtime(fn);
816}
817
818
819double object_mtime(const char *id)
820{
821 xs *md5 = xs_md5_hex(id, strlen(id));
822 return object_mtime_by_md5(md5);
823}
824
825
826void object_touch(const char *id)
827{
828 xs *md5 = xs_md5_hex(id, strlen(id));
829 xs *fn = _object_fn_by_md5(md5, "object_touch");
830
831 if (mtime(fn))
832 utimes(fn, NULL);
833}
834
835
799xs_str *_object_index_fn(const char *id, const char *idxsfx) 836xs_str *_object_index_fn(const char *id, const char *idxsfx)
800/* returns the filename of an object's index */ 837/* returns the filename of an object's index */
801{ 838{
@@ -880,6 +917,9 @@ int object_unadmire(const char *id, const char *actor, int like)
880 917
881 status = index_del(fn, actor); 918 status = index_del(fn, actor);
882 919
920 if (valid_status(status))
921 index_gc(fn);
922
883 srv_debug(0, 923 srv_debug(0,
884 xs_fmt("object_unadmire (%s) %s %s %d", like ? "Like" : "Announce", actor, fn, status)); 924 xs_fmt("object_unadmire (%s) %s %s %d", like ? "Like" : "Announce", actor, fn, status));
885 925
@@ -1551,7 +1591,6 @@ int actor_get(const char *actor, xs_dict **data)
1551 else 1591 else
1552 d = xs_free(d); 1592 d = xs_free(d);
1553 1593
1554#ifdef STALE_ACTORS
1555 xs *fn = _object_fn(actor); 1594 xs *fn = _object_fn(actor);
1556 double max_time; 1595 double max_time;
1557 1596
@@ -1560,13 +1599,20 @@ int actor_get(const char *actor, xs_dict **data)
1560 1599
1561 if (mtime(fn) + max_time < (double) time(NULL)) { 1600 if (mtime(fn) + max_time < (double) time(NULL)) {
1562 /* actor data exists but also stinks */ 1601 /* actor data exists but also stinks */
1563
1564 /* touch the file */
1565 utimes(fn, NULL);
1566
1567 status = 205; /* "205: Reset Content" "110: Response Is Stale" */ 1602 status = 205; /* "205: Reset Content" "110: Response Is Stale" */
1568 } 1603 }
1569#endif /* STALE_ACTORS */ 1604
1605 return status;
1606}
1607
1608
1609int actor_get_refresh(snac *user, const char *actor, xs_dict **data)
1610/* gets an actor and requests a refresh if it's stale */
1611{
1612 int status = actor_get(actor, data);
1613
1614 if (status == 205 && user && !xs_startswith(actor, srv_baseurl))
1615 enqueue_actor_refresh(user, actor);
1570 1616
1571 return status; 1617 return status;
1572} 1618}
@@ -2007,6 +2053,47 @@ int instance_unblock(const char *instance)
2007} 2053}
2008 2054
2009 2055
2056/** content filtering **/
2057
2058int content_check(const char *file, const xs_dict *msg)
2059/* checks if a message's content matches any of the regexes in file */
2060/* file format: one regex per line */
2061{
2062 xs *fn = xs_fmt("%s/%s", srv_basedir, file);
2063 FILE *f;
2064 int r = 0;
2065 char *v = xs_dict_get(msg, "content");
2066
2067 if (xs_type(v) == XSTYPE_STRING && *v) {
2068 if ((f = fopen(fn, "r")) != NULL) {
2069 srv_debug(1, xs_fmt("content_check: loading regexes from %s", fn));
2070
2071 /* massage content (strip HTML tags, etc.) */
2072 xs *c = xs_regex_replace(v, "<[^>]+>", " ");
2073 c = xs_regex_replace_i(c, " {2,}", " ");
2074 c = xs_tolower_i(c);
2075
2076 while (!r && !feof(f)) {
2077 xs *rx = xs_strip_i(xs_readline(f));
2078
2079 if (*rx) {
2080 xs *l = xs_regex_select_n(c, rx, 1);
2081
2082 if (xs_list_len(l)) {
2083 srv_debug(1, xs_fmt("content_check: match for '%s'", rx));
2084 r = 1;
2085 }
2086 }
2087 }
2088
2089 fclose(f);
2090 }
2091 }
2092
2093 return r;
2094}
2095
2096
2010/** notifications **/ 2097/** notifications **/
2011 2098
2012xs_str *notify_check_time(snac *snac, int reset) 2099xs_str *notify_check_time(snac *snac, int reset)
@@ -2388,6 +2475,21 @@ void enqueue_verify_links(snac *user)
2388} 2475}
2389 2476
2390 2477
2478void enqueue_actor_refresh(snac *user, const char *actor)
2479/* enqueues an actor refresh */
2480{
2481 xs *qmsg = _new_qmsg("actor_refresh", "", 0);
2482 char *ntid = xs_dict_get(qmsg, "ntid");
2483 xs *fn = xs_fmt("%s/queue/%s.json", user->basedir, ntid);
2484
2485 qmsg = xs_dict_append(qmsg, "actor", actor);
2486
2487 qmsg = _enqueue_put(fn, qmsg);
2488
2489 snac_debug(user, 1, xs_fmt("enqueue_actor_refresh %s", actor));
2490}
2491
2492
2391void enqueue_request_replies(snac *user, const char *id) 2493void enqueue_request_replies(snac *user, const char *id)
2392/* enqueues a request for the replies of a message */ 2494/* enqueues a request for the replies of a message */
2393{ 2495{
@@ -2645,6 +2747,16 @@ void purge_server(void)
2645 } 2747 }
2646 } 2748 }
2647 } 2749 }
2750
2751 /* delete index backups */
2752 xs *specb = xs_fmt("%s/" "*.bak", v);
2753 xs *bakfs = xs_glob(specb, 0, 0);
2754
2755 p2 = bakfs;
2756 while (xs_list_iter(&p2, &v2)) {
2757 unlink(v2);
2758 srv_debug(1, xs_fmt("purged %s", v2));
2759 }
2648 } 2760 }
2649 } 2761 }
2650 2762