annotate plugins/links/links.c @ 1011:a35537c50f09

irccd: hide conn implementation
author David Demelier <markand@malikania.fr>
date Wed, 17 Feb 2021 20:05:00 +0100
parents 936cbd66b4b8
children a20060091063
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
987
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * links.c -- links plugin
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2013-2021 David Demelier <markand@malikania.fr>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include <assert.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #include <ctype.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include <err.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 #include <errno.h>
1011
a35537c50f09 irccd: hide conn implementation
David Demelier <markand@malikania.fr>
parents: 1007
diff changeset
23 #include <pthread.h>
987
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 #include <regex.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 #include <stdio.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
26 #include <stdlib.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 #include <string.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
28
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 #include <curl/curl.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
30
992
462e12e434fb cmake: add CMake configuration
David Demelier <markand@malikania.fr>
parents: 990
diff changeset
31 #include <irccd/compat.h>
1011
a35537c50f09 irccd: hide conn implementation
David Demelier <markand@malikania.fr>
parents: 1007
diff changeset
32 #include <irccd/config.h>
987
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 #include <irccd/irccd.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 #include <irccd/limits.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 #include <irccd/server.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 #include <irccd/subst.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 #include <irccd/util.h>
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
38
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 /*
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 * Since most websites are now bloated, we need a very large page size to
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 * analyse. Use 5MB for now.
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 */
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 #define PAGE_MAX 5242880
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
44
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 struct req {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 pthread_t thr;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 CURL *curl;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 struct irc_server *server;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 int status;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 char *link;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 char *chan;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 char *nickname;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 char *origin;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 FILE *fp;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 char buf[];
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 };
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
57
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 enum {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 TPL_INFO
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 };
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
61
990
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
62 static unsigned long timeout = 30;
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
63
987
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 static char templates[][512] = {
1007
936cbd66b4b8 plugin links: fix a leak
David Demelier <markand@malikania.fr>
parents: 992
diff changeset
65 [TPL_INFO] = "link from #{nickname}: #{title}"
987
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 };
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
67
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 static size_t
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 callback(char *ptr, size_t size, size_t nmemb, struct req *req)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 fprintf(req->fp, "%.*s", (int)(size * nmemb), ptr);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
72
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 if (feof(req->fp) || ferror(req->fp))
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 return 0;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
75
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 return size * nmemb;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
78
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 static const char *
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 parse(struct req *req)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 regex_t regex;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 regmatch_t match[2];
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 char *ret = NULL;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
85
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 if (regcomp(&regex, "<title>([^<]+)<\\/title>", REG_EXTENDED | REG_ICASE) != 0)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 return NULL;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
88
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 if (regexec(&regex, req->buf, 2, match, 0) == 0) {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 ret = &req->buf[match[1].rm_so];
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 ret[match[1].rm_eo - match[1].rm_so] = '\0';
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
93
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
94 regfree(&regex);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
95
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 return ret;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
97 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
98
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 static const char *
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 fmt(const struct req *req, const char *title)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 static char line[IRC_MESSAGE_LEN];
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 struct irc_subst subst = {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 .time = time(NULL),
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 .flags = IRC_SUBST_DATE | IRC_SUBST_KEYWORDS | IRC_SUBST_IRC_ATTRS,
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 .keywords = (struct irc_subst_keyword []) {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 { "channel", req->chan },
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 { "nickname", req->nickname },
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 { "origin", req->origin },
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 { "server", req->server->name },
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 { "title", title }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
112 },
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 .keywordsz = 5
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 };
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
115
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 irc_subst(line, sizeof (line), templates[TPL_INFO], &subst);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
117
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 return line;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
119 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
120
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 static void
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 req_finish(struct req *);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
123
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 static void
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 complete(struct req *req)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 const char *title;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
128
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 if (req->status && (title = parse(req)))
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
130 irc_server_message(req->server, req->chan, fmt(req, title));
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
131
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
132 pthread_join(req->thr, NULL);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 req_finish(req);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
135
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 /*
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 * This function is running in a separate thread.
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
138 */
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 static void *
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 routine(struct req *req)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 typedef void (*func_t)(void *);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
143
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 if (curl_easy_perform(req->curl) == 0)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 req->status = 1;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
146
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 irc_bot_post((func_t)complete, req);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
148
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 return NULL;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
151
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 static void
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 req_finish(struct req *req)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 assert(req);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
156
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 if (req->server)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 irc_server_decref(req->server);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 if (req->curl)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
160 curl_easy_cleanup(req->curl);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 if (req->fp)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 fclose(req->fp);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
163
1007
936cbd66b4b8 plugin links: fix a leak
David Demelier <markand@malikania.fr>
parents: 992
diff changeset
164 free(req->link);
987
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 free(req->chan);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 free(req->nickname);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 free(req->origin);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 free(req);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
170
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 static struct req *
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 req_new(struct irc_server *server, const char *origin, const char *channel, char *link)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 assert(link);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
175
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 struct req *req;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 struct irc_server_user user;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
178
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 if (!(req = calloc(1, sizeof (*req) + PAGE_MAX + 1))) {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 free(link);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 return NULL;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 if (!(req->curl = curl_easy_init()))
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 goto enomem;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 if (!(req->fp = fmemopen(req->buf, PAGE_MAX, "w")))
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 goto enomem;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
187
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 irc_server_incref(server);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 irc_server_split(origin, &user);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 req->link = link;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 req->server = server;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 req->chan = strdup(channel);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 req->nickname = strdup(user.nickname);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 req->origin = strdup(origin);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
195
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 curl_easy_setopt(req->curl, CURLOPT_URL, link);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 curl_easy_setopt(req->curl, CURLOPT_FOLLOWLOCATION, 1L);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 curl_easy_setopt(req->curl, CURLOPT_WRITEFUNCTION, callback);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 curl_easy_setopt(req->curl, CURLOPT_WRITEDATA, req);
990
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
200 curl_easy_setopt(req->curl, CURLOPT_TIMEOUT, timeout);
987
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
201
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 return req;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
203
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
204 enomem:
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 errno = ENOMEM;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 req_finish(req);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
207
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 return NULL;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
210
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
211 static void
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 req_start(struct req *req)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 typedef void *(*func_t)(void *);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
215
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 if (pthread_create(&req->thr, NULL, (func_t)routine, req) != 0)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 req_finish(req);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
218 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
219
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
220 void
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 links_event(const struct irc_event *ev)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
222 {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 struct req *req;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
224 char *loc, *link, *end;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
225
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 if (ev->type != IRC_EVENT_MESSAGE)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 return;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
228
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 /* Parse link. */
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
230 if (!(loc = strstr(ev->message.message, "http://")) &&
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
231 !(loc = strstr(ev->message.message, "https://")))
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
232 return;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
233
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 /* Compute end to allocate only what's needed. */
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
235 for (end = loc; *end && !isspace(*end); )
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
236 ++end;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
237
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
238 link = irc_util_strndup(loc, end - loc);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
239
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 /* If the function fails, link is free'd anyway. */
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 if (!(req = req_new(ev->server, ev->message.origin, ev->message.channel, link)))
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
242 return;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
243
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
244 req_start(req);
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
246
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
247 void
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
248 links_set_template(const char *key, const char *value)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
249 {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 if (strcmp(key, "info") == 0)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 strlcpy(templates[TPL_INFO], value, sizeof (templates[TPL_INFO]));
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
252 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
253
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
254 const char *
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
255 links_get_template(const char *key)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
257 if (strcmp(key, "info") == 0)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 return templates[TPL_INFO];
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
259
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
260 return NULL;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 }
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
262
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 const char **
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 links_get_templates(void)
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
265 {
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
266 static const char *keys[] = { "info", NULL };
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
267
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
268 return keys;
685b85367c8e plugin logger: resurrect
David Demelier <markand@malikania.fr>
parents:
diff changeset
269 }
988
2e02fbb8b32b irccd: load metadata from native plugins
David Demelier <markand@malikania.fr>
parents: 987
diff changeset
270
990
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
271 void
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
272 links_set_option(const char *key, const char *value)
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
273 {
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
274 if (strcmp(key, "timeout") == 0)
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
275 timeout = atol(value);
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
276 }
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
277
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
278 const char *
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
279 links_get_option(const char *key)
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
280 {
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
281 static char out[32];
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
282
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
283 if (strcmp(key, "timeout") == 0) {
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
284 snprintf(out, sizeof (out), "%lu", timeout);
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
285 return out;
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
286 }
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
287
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
288 return NULL;
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
289 }
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
290
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
291 const char **
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
292 links_get_options(void)
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
293 {
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
294 static const char *keys[] = { "timeout", NULL };
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
295
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
296 return keys;
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
297 }
daaf92c097e6 plugin links: add timeout support
David Demelier <markand@malikania.fr>
parents: 988
diff changeset
298
988
2e02fbb8b32b irccd: load metadata from native plugins
David Demelier <markand@malikania.fr>
parents: 987
diff changeset
299 const char *links_description = "Parse links from messages";
2e02fbb8b32b irccd: load metadata from native plugins
David Demelier <markand@malikania.fr>
parents: 987
diff changeset
300 const char *links_version = IRCCD_VERSION;
2e02fbb8b32b irccd: load metadata from native plugins
David Demelier <markand@malikania.fr>
parents: 987
diff changeset
301 const char *links_license = "ISC";
2e02fbb8b32b irccd: load metadata from native plugins
David Demelier <markand@malikania.fr>
parents: 987
diff changeset
302 const char *links_author = "David Demelier <markand@malikania.fr>";