summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorGravatar Oliver2025-07-16 20:21:20 +0200
committerGravatar Oliver2025-07-16 20:21:20 +0200
commit3554a73aa50526631961efcca78c6c8eb2a16911 (patch)
treefc4c21a65337ab8ecb4fb00aa551ee21997faf6f /main.c
parentpo/de_DE.po aktualisiert (diff)
parentUpdated RELEASE_NOTES. (diff)
downloadsnac2-3554a73aa50526631961efcca78c6c8eb2a16911.tar.gz
snac2-3554a73aa50526631961efcca78c6c8eb2a16911.tar.xz
snac2-3554a73aa50526631961efcca78c6c8eb2a16911.zip
Merge pull request 'master' (#9) from grunfink/snac2:master into master
Reviewed-on: https://codeberg.org/zen/snac2/pulls/9
Diffstat (limited to 'main.c')
-rw-r--r--main.c166
1 files changed, 108 insertions, 58 deletions
diff --git a/main.c b/main.c
index 80df2d0..ce4e7ce 100644
--- a/main.c
+++ b/main.c
@@ -7,64 +7,90 @@
7#include "xs_time.h" 7#include "xs_time.h"
8#include "xs_openssl.h" 8#include "xs_openssl.h"
9#include "xs_match.h" 9#include "xs_match.h"
10#include "xs_random.h"
10 11
11#include "snac.h" 12#include "snac.h"
12 13
13#include <sys/stat.h> 14#include <sys/stat.h>
14#include <sys/wait.h> 15#include <sys/wait.h>
15 16
16int usage(void) 17int usage(const char *cmd)
17{ 18{
18 printf("snac " VERSION " - A simple, minimalistic ActivityPub instance\n"); 19 printf("snac " VERSION " - A simple, minimalistic ActivityPub instance\n");
19 printf("Copyright (c) 2022 - 2025 grunfink et al. / MIT license\n"); 20 printf("Copyright (c) 2022 - 2025 grunfink et al. / MIT license\n");
20 printf("\n"); 21 printf("\n");
21 printf("Commands:\n"); 22
22 printf("\n"); 23 if (cmd == NULL) {
23 printf("init [{basedir}] Initializes the data storage\n"); 24 printf("Commands:\n");
24 printf("upgrade {basedir} Upgrade to a new version\n"); 25 printf("\n");
25 printf("adduser {basedir} [{uid}] Adds a new user\n"); 26 }
26 printf("deluser {basedir} {uid} Deletes a user\n"); 27
27 printf("httpd {basedir} Starts the HTTPD daemon\n"); 28 const char *cmds =
28 printf("purge {basedir} Purges old data\n"); 29 "init [{basedir}] Initializes the data storage\n"
29 printf("state {basedir} Prints server state\n"); 30 "upgrade {basedir} Upgrade to a new version\n"
30 printf("webfinger {basedir} {account} Queries about an account (@user@host or actor url)\n"); 31 "adduser {basedir} [{uid}] Adds a new user\n"
31 printf("queue {basedir} {uid} Processes a user queue\n"); 32 "deluser {basedir} {uid} Deletes a user\n"
32 printf("follow {basedir} {uid} {actor} Follows an actor\n"); 33 "httpd {basedir} Starts the HTTPD daemon\n"
33 printf("unfollow {basedir} {uid} {actor} Unfollows an actor\n"); 34 "purge {basedir} Purges old data\n"
34 printf("request {basedir} {uid} {url} Requests an object\n"); 35 "state {basedir} Prints server state\n"
35 printf("insert {basedir} {uid} {url} Requests an object and inserts it into the timeline\n"); 36 "webfinger {basedir} {account} Queries about an account (@user@host or actor url)\n"
36 printf("actor {basedir} [{uid}] {url} Requests an actor\n"); 37 "queue {basedir} {uid} Processes a user queue\n"
37 printf("note {basedir} {uid} {text} [files...] Sends a note with optional attachments\n"); 38 "follow {basedir} {uid} {actor} Follows an actor\n"
38 printf("note_unlisted {basedir} {uid} {text} [files...] Sends an unlisted note with optional attachments\n"); 39 "unfollow {basedir} {uid} {actor} Unfollows an actor\n"
39 printf("note_mention {basedir} {uid} {text} [files...] Sends a note only to mentioned accounts\n"); 40 "request {basedir} {uid} {url} Requests an object\n"
40 printf("boost|announce {basedir} {uid} {url} Boosts (announces) a post\n"); 41 "insert {basedir} {uid} {url} Requests an object and inserts it into the timeline\n"
41 printf("unboost {basedir} {uid} {url} Unboosts a post\n"); 42 "actor {basedir} [{uid}] {url} Requests an actor\n"
42 printf("resetpwd {basedir} {uid} Resets the password of a user\n"); 43 "note {basedir} {uid} {text} [files...] Sends a note with optional attachments\n"
43 printf("ping {basedir} {uid} {actor} Pings an actor\n"); 44 "note_unlisted {basedir} {uid} {text} [files...] Sends an unlisted note with optional attachments\n"
44 printf("webfinger_s {basedir} {uid} {account} Queries about an account (@user@host or actor url)\n"); 45 "note_mention {basedir} {uid} {text} [files...] Sends a note only to mentioned accounts\n"
45 printf("pin {basedir} {uid} {msg_url} Pins a message\n"); 46 "boost|announce {basedir} {uid} {url} Boosts (announces) a post\n"
46 printf("unpin {basedir} {uid} {msg_url} Unpins a message\n"); 47 "unboost {basedir} {uid} {url} Unboosts a post\n"
47 printf("bookmark {basedir} {uid} {msg_url} Bookmarks a message\n"); 48 "resetpwd {basedir} {uid} Resets the password of a user\n"
48 printf("unbookmark {basedir} {uid} {msg_url} Unbookmarks a message\n"); 49 "ping {basedir} {uid} {actor} Pings an actor\n"
49 printf("block {basedir} {instance_url} Blocks a full instance\n"); 50 "webfinger_s {basedir} {uid} {account} Queries about an account (@user@host or actor url)\n"
50 printf("unblock {basedir} {instance_url} Unblocks a full instance\n"); 51 "pin {basedir} {uid} {msg_url} Pins a message\n"
51 printf("limit {basedir} {uid} {actor} Limits an actor (drops their announces)\n"); 52 "unpin {basedir} {uid} {msg_url} Unpins a message\n"
52 printf("unlimit {basedir} {uid} {actor} Unlimits an actor\n"); 53 "bookmark {basedir} {uid} {msg_url} Bookmarks a message\n"
53 printf("unmute {basedir} {uid} {actor} Unmutes a previously muted actor\n"); 54 "unbookmark {basedir} {uid} {msg_url} Unbookmarks a message\n"
54 printf("verify_links {basedir} {uid} Verifies a user's links (in the metadata)\n"); 55 "block {basedir} {instance_url} Blocks a full instance\n"
55 printf("search {basedir} {uid} {regex} Searches posts by content\n"); 56 "unblock {basedir} {instance_url} Unblocks a full instance\n"
56 printf("export_csv {basedir} {uid} Exports data as CSV files\n"); 57 "limit {basedir} {uid} {actor} Limits an actor (drops their announces)\n"
57 printf("alias {basedir} {uid} {account} Sets account (@user@host or actor url) as an alias\n"); 58 "unlimit {basedir} {uid} {actor} Unlimits an actor\n"
58 printf("migrate {basedir} {uid} Migrates to the account defined as the alias\n"); 59 "unmute {basedir} {uid} {actor} Unmutes a previously muted actor\n"
59 printf("import_csv {basedir} {uid} Imports data from CSV files\n"); 60 "verify_links {basedir} {uid} Verifies a user's links (in the metadata)\n"
60 printf("import_list {basedir} {uid} {file} Imports a Mastodon CSV list file\n"); 61 "search {basedir} {uid} {regex} Searches posts by content\n"
61 printf("import_block_list {basedir} {uid} {file} Imports a Mastodon CSV block list file\n"); 62 "export_csv {basedir} {uid} Exports followers, lists, MUTEd and bookmarks to CSV\n"
62 printf("lists {basedir} {uid} Returns the names of the lists created by the user\n"); 63 "export_posts {basedir} {iod} Exports all posts to outbox.json\n"
63 printf("list_members {basedir} {uid} {name} Returns the list of accounts inside a list\n"); 64 "alias {basedir} {uid} {account} Sets account (@user@host or actor url) as an alias\n"
64 printf("create_list {basedir} {uid} {name} Creates a new list\n"); 65 "migrate {basedir} {uid} Migrates to the account defined as the alias\n"
65 printf("delete_list {basedir} {uid} {name} Deletes an existing list\n"); 66 "import_csv {basedir} {uid} Imports data from CSV files\n"
66 printf("list_add {basedir} {uid} {name} {acct} Adds an account (@user@host or actor url) to a list\n"); 67 "import_list {basedir} {uid} {file} Imports a Mastodon CSV list file\n"
67 printf("list_del {basedir} {uid} {name} {actor} Deletes an actor URL from a list\n"); 68 "import_block_list {basedir} {uid} {file} Imports a Mastodon CSV block list file\n"
69 "lists {basedir} {uid} Returns the names of the lists created by the user\n"
70 "list_members {basedir} {uid} {name} Returns the list of accounts inside a list\n"
71 "list_create {basedir} {uid} {name} Creates a new list\n"
72 "list_remove {basedir} {uid} {name} Removes an existing list\n"
73 "list_add {basedir} {uid} {name} {acct} Adds an account (@user@host or actor url) to a list\n"
74 "list_del {basedir} {uid} {name} {actor} Deletes an actor URL from a list\n";
75
76 if (cmd == NULL)
77 printf("%s", cmds);
78 else {
79 /* only show help for the entered command */
80 xs *l = xs_split(cmds, "\n");
81 const char *v;
82 int cnt = 0;
83
84 xs_list_foreach(l, v) {
85 if (xs_str_in(v, cmd) != -1) {
86 printf("%s\n", v);
87 cnt++;
88 }
89 }
90
91 if (cnt == 0)
92 printf("%s", cmds);
93 }
68 94
69 return 1; 95 return 1;
70} 96}
@@ -94,7 +120,7 @@ int main(int argc, char *argv[])
94 umask(0007); 120 umask(0007);
95 121
96 if ((cmd = GET_ARGV()) == NULL) 122 if ((cmd = GET_ARGV()) == NULL)
97 return usage(); 123 return usage(cmd);
98 124
99 if (strcmp(cmd, "init") == 0) { /** **/ 125 if (strcmp(cmd, "init") == 0) { /** **/
100 /* initialize the data storage */ 126 /* initialize the data storage */
@@ -106,7 +132,7 @@ int main(int argc, char *argv[])
106 132
107 if ((basedir = getenv("SNAC_BASEDIR")) == NULL) { 133 if ((basedir = getenv("SNAC_BASEDIR")) == NULL) {
108 if ((basedir = GET_ARGV()) == NULL) 134 if ((basedir = GET_ARGV()) == NULL)
109 return usage(); 135 return usage(cmd);
110 } 136 }
111 137
112 if (strcmp(cmd, "upgrade") == 0) { /** **/ 138 if (strcmp(cmd, "upgrade") == 0) { /** **/
@@ -143,6 +169,11 @@ int main(int argc, char *argv[])
143 return 0; 169 return 0;
144 } 170 }
145 171
172 if (strcmp(cmd, "poll_hashtag_rss") == 0) { /** **/
173 rss_poll_hashtags();
174 return 0;
175 }
176
146 if (strcmp(cmd, "state") == 0) { /** **/ 177 if (strcmp(cmd, "state") == 0) { /** **/
147 xs *shm_name = NULL; 178 xs *shm_name = NULL;
148 srv_state *p_state = srv_state_op(&shm_name, 1); 179 srv_state *p_state = srv_state_op(&shm_name, 1);
@@ -167,7 +198,7 @@ int main(int argc, char *argv[])
167 } 198 }
168 199
169 if ((user = GET_ARGV()) == NULL) 200 if ((user = GET_ARGV()) == NULL)
170 return usage(); 201 return usage(cmd);
171 202
172 if (strcmp(cmd, "block") == 0) { /** **/ 203 if (strcmp(cmd, "block") == 0) { /** **/
173 int ret = instance_block(user); 204 int ret = instance_block(user);
@@ -279,6 +310,11 @@ int main(int argc, char *argv[])
279 return 0; 310 return 0;
280 } 311 }
281 312
313 if (strcmp(cmd, "export_posts") == 0) { /** **/
314 export_posts(&snac);
315 return 0;
316 }
317
282 if (strcmp(cmd, "import_csv") == 0) { /** **/ 318 if (strcmp(cmd, "import_csv") == 0) { /** **/
283 import_csv(&snac); 319 import_csv(&snac);
284 return 0; 320 return 0;
@@ -300,7 +336,7 @@ int main(int argc, char *argv[])
300 } 336 }
301 337
302 if ((url = GET_ARGV()) == NULL) 338 if ((url = GET_ARGV()) == NULL)
303 return usage(); 339 return usage(cmd);
304 340
305 if (strcmp(cmd, "list_members") == 0) { /** **/ 341 if (strcmp(cmd, "list_members") == 0) { /** **/
306 xs *lid = list_maint(&snac, url, 4); 342 xs *lid = list_maint(&snac, url, 4);
@@ -323,7 +359,7 @@ int main(int argc, char *argv[])
323 return 0; 359 return 0;
324 } 360 }
325 361
326 if (strcmp(cmd, "create_list") == 0) { /** **/ 362 if (strcmp(cmd, "list_create") == 0) { /** **/
327 xs *lid = list_maint(&snac, url, 4); 363 xs *lid = list_maint(&snac, url, 4);
328 364
329 if (lid == NULL) { 365 if (lid == NULL) {
@@ -336,7 +372,7 @@ int main(int argc, char *argv[])
336 return 0; 372 return 0;
337 } 373 }
338 374
339 if (strcmp(cmd, "delete_list") == 0) { /** **/ 375 if (strcmp(cmd, "list_remove") == 0) { /** **/
340 xs *lid = list_maint(&snac, url, 4); 376 xs *lid = list_maint(&snac, url, 4);
341 377
342 if (lid != NULL) { 378 if (lid != NULL) {
@@ -744,12 +780,24 @@ int main(int argc, char *argv[])
744 xs *msg = NULL; 780 xs *msg = NULL;
745 xs *c_msg = NULL; 781 xs *c_msg = NULL;
746 xs *attl = xs_list_new(); 782 xs *attl = xs_list_new();
747 char *fn = NULL; 783 const char *fn = NULL;
784 const char *in_reply_to = NULL;
785 const char **next = NULL;
748 786
749 /* iterate possible attachments */ 787 /* iterate possible attachments */
750 while ((fn = GET_ARGV())) { 788 while ((fn = GET_ARGV())) {
751 FILE *f; 789 FILE *f;
752 790
791 if (next) {
792 *next = fn;
793 next = NULL;
794 }
795 else
796 if (strcmp(fn, "-r") == 0) {
797 /* next argument is an inReplyTo */
798 next = &in_reply_to;
799 }
800 else
753 if ((f = fopen(fn, "rb")) != NULL) { 801 if ((f = fopen(fn, "rb")) != NULL) {
754 /* get the file size and content */ 802 /* get the file size and content */
755 fseek(f, 0, SEEK_END); 803 fseek(f, 0, SEEK_END);
@@ -759,8 +807,10 @@ int main(int argc, char *argv[])
759 fclose(f); 807 fclose(f);
760 808
761 char *ext = strrchr(fn, '.'); 809 char *ext = strrchr(fn, '.');
762 xs *hash = xs_md5_hex(fn, strlen(fn)); 810 char rnd[32];
763 xs *id = xs_fmt("%s%s", hash, ext); 811 xs_rnd_buf(rnd, sizeof(rnd));
812 xs *hash = xs_md5_hex(rnd, sizeof(rnd));
813 xs *id = xs_fmt("post-%s%s", hash, ext ? ext : "");
764 xs *url = xs_fmt("%s/s/%s", snac.actor, id); 814 xs *url = xs_fmt("%s/s/%s", snac.actor, id);
765 815
766 /* store */ 816 /* store */
@@ -821,7 +871,7 @@ int main(int argc, char *argv[])
821 if (strcmp(cmd, "note_unlisted") == 0) 871 if (strcmp(cmd, "note_unlisted") == 0)
822 scope = 2; 872 scope = 2;
823 873
824 msg = msg_note(&snac, content, NULL, NULL, attl, scope, getenv("LANG"), NULL); 874 msg = msg_note(&snac, content, NULL, in_reply_to, attl, scope, getenv("LANG"), NULL);
825 875
826 c_msg = msg_create(&snac, msg); 876 c_msg = msg_create(&snac, msg);
827 877