Implement URL opening
parent
f502260dd0
commit
9b9794df33
73
url.c
73
url.c
|
@ -14,12 +14,15 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sysexits.h>
|
#include <sysexits.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "chat.h"
|
#include "chat.h"
|
||||||
|
|
||||||
|
@ -55,26 +58,31 @@ static void compile(void) {
|
||||||
errx(EX_SOFTWARE, "regcomp: %s: %s", buf, Pattern);
|
errx(EX_SOFTWARE, "regcomp: %s: %s", buf, Pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct URL {
|
||||||
|
size_t id;
|
||||||
|
char *nick;
|
||||||
|
char *url;
|
||||||
|
};
|
||||||
|
|
||||||
enum { Cap = 32 };
|
enum { Cap = 32 };
|
||||||
static struct {
|
static struct {
|
||||||
size_t ids[Cap];
|
struct URL urls[Cap];
|
||||||
char *nicks[Cap];
|
|
||||||
char *urls[Cap];
|
|
||||||
size_t len;
|
size_t len;
|
||||||
} ring;
|
} ring;
|
||||||
|
static_assert(!(Cap & (Cap - 1)), "Cap is power of two");
|
||||||
|
|
||||||
static void push(size_t id, const char *nick, const char *url, size_t len) {
|
static void push(size_t id, const char *nick, const char *str, size_t len) {
|
||||||
size_t i = ring.len++ % Cap;
|
struct URL *url = &ring.urls[ring.len++ % Cap];
|
||||||
free(ring.nicks[i]);
|
free(url->nick);
|
||||||
free(ring.urls[i]);
|
free(url->url);
|
||||||
ring.ids[i] = id;
|
url->id = id;
|
||||||
ring.nicks[i] = NULL;
|
url->nick = NULL;
|
||||||
if (nick) {
|
if (nick) {
|
||||||
ring.nicks[i] = strdup(nick);
|
url->nick = strdup(nick);
|
||||||
if (!ring.nicks[i]) err(EX_OSERR, "strdup");
|
if (!url->nick) err(EX_OSERR, "strdup");
|
||||||
}
|
}
|
||||||
ring.urls[i] = strndup(url, len);
|
url->url = strndup(str, len);
|
||||||
if (!ring.urls[i]) err(EX_OSERR, "strndup");
|
if (!url->url) err(EX_OSERR, "strndup");
|
||||||
}
|
}
|
||||||
|
|
||||||
void urlScan(size_t id, const char *nick, const char *mesg) {
|
void urlScan(size_t id, const char *nick, const char *mesg) {
|
||||||
|
@ -87,10 +95,45 @@ void urlScan(size_t id, const char *nick, const char *mesg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *OpenBins[] = { "open", "xdg-open" };
|
||||||
|
|
||||||
|
static void urlOpen(const char *url) {
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid < 0) err(EX_OSERR, "fork");
|
||||||
|
if (pid) return;
|
||||||
|
|
||||||
|
close(STDIN_FILENO);
|
||||||
|
dup2(procPipe[1], STDOUT_FILENO);
|
||||||
|
dup2(procPipe[1], STDERR_FILENO);
|
||||||
|
for (size_t i = 0; i < ARRAY_LEN(OpenBins); ++i) {
|
||||||
|
execlp(OpenBins[i], OpenBins[i], url, NULL);
|
||||||
|
if (errno != ENOENT) {
|
||||||
|
warn("%s", OpenBins[i]);
|
||||||
|
_exit(EX_CONFIG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
warnx("no open utility found");
|
||||||
|
_exit(EX_CONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
void urlOpenCount(size_t id, size_t count) {
|
void urlOpenCount(size_t id, size_t count) {
|
||||||
// TODO
|
for (size_t i = 1; i <= Cap; ++i) {
|
||||||
|
const struct URL *url = &ring.urls[(ring.len - i) % Cap];
|
||||||
|
if (!url->url) break;
|
||||||
|
if (url->id != id) continue;
|
||||||
|
urlOpen(url->url);
|
||||||
|
if (!--count) break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void urlOpenMatch(size_t id, const char *str) {
|
void urlOpenMatch(size_t id, const char *str) {
|
||||||
// TODO
|
for (size_t i = 1; i <= Cap; ++i) {
|
||||||
|
const struct URL *url = &ring.urls[(ring.len - i) % Cap];
|
||||||
|
if (!url->url) break;
|
||||||
|
if (url->id != id) continue;
|
||||||
|
if ((url->nick && !strcmp(url->nick, str)) || strstr(url->url, str)) {
|
||||||
|
urlOpen(url->url);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue