aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Routes/Search.c57
-rw-r--r--src/Routes/Settings.c60
-rw-r--r--src/Routes/SettingsSave.c32
-rw-r--r--src/Utility/Utility.c84
-rw-r--r--src/Utility/Utility.h4
5 files changed, 233 insertions, 4 deletions
diff --git a/src/Routes/Search.c b/src/Routes/Search.c
index e201e10..f0c5ad1 100644
--- a/src/Routes/Search.c
+++ b/src/Routes/Search.c
@@ -290,6 +290,13 @@ static const SearchEngine *find_enabled_engine(const char *engine_id) {
return NULL;
}
+static int engine_allowed_for_user(const SearchEngine *eng, char **user_ids,
+ int user_count, int has_pref) {
+ if (!has_pref)
+ return 1;
+ return user_engines_contains(eng->id, user_ids, user_count);
+}
+
static char *build_search_href(const char *query, const char *engine_id,
int page) {
const char *safe_query = query ? query : "";
@@ -350,6 +357,10 @@ int results_handler(UrlParams *params) {
int page = 1;
int btnI = 0;
+ char **user_engines = NULL;
+ int user_engine_count = 0;
+ int has_user_pref = (get_user_engines(&user_engines, &user_engine_count) == 0);
+
if (params) {
for (int i = 0; i < params->count; i++) {
if (strcmp(params->params[i].key, "q") == 0) {
@@ -396,6 +407,11 @@ int results_handler(UrlParams *params) {
if (!raw_query || strlen(raw_query) == 0) {
send_redirect("/");
+ if (has_user_pref) {
+ for (int i = 0; i < user_engine_count; i++)
+ free(user_engines[i]);
+ free(user_engines);
+ }
free_context(&ctx);
return -1;
}
@@ -412,7 +428,9 @@ int results_handler(UrlParams *params) {
int enabled_engine_count = 0;
for (int i = 0; i < ENGINE_COUNT; i++) {
if (ENGINE_REGISTRY[i].enabled &&
- (!selected_engine || &ENGINE_REGISTRY[i] == selected_engine)) {
+ (!selected_engine || &ENGINE_REGISTRY[i] == selected_engine) &&
+ engine_allowed_for_user(&ENGINE_REGISTRY[i], user_engines,
+ user_engine_count, has_user_pref)) {
enabled_engine_count++;
}
}
@@ -439,7 +457,9 @@ int results_handler(UrlParams *params) {
int engine_idx = 0;
for (int i = 0; i < ENGINE_COUNT; i++) {
if (ENGINE_REGISTRY[i].enabled &&
- (!selected_engine || &ENGINE_REGISTRY[i] == selected_engine)) {
+ (!selected_engine || &ENGINE_REGISTRY[i] == selected_engine) &&
+ engine_allowed_for_user(&ENGINE_REGISTRY[i], user_engines,
+ user_engine_count, has_user_pref)) {
all_results[engine_idx] = NULL;
jobs[engine_idx].engine = &ENGINE_REGISTRY[i];
jobs[engine_idx].query = raw_query;
@@ -488,6 +508,11 @@ int results_handler(UrlParams *params) {
snprintf(response, sizeof(response), "<h1>%s</h1>", rate_limit_msg);
send_response(response);
free(request_cache_key);
+ if (has_user_pref) {
+ for (int i = 0; i < user_engine_count; i++)
+ free(user_engines[i]);
+ free(user_engines);
+ }
free_context(&ctx);
return -1;
}
@@ -499,7 +524,9 @@ int results_handler(UrlParams *params) {
int filter_engine_count = 0;
for (int i = 0; i < ENGINE_COUNT; i++) {
- if (ENGINE_REGISTRY[i].enabled)
+ if (ENGINE_REGISTRY[i].enabled &&
+ engine_allowed_for_user(&ENGINE_REGISTRY[i], user_engines,
+ user_engine_count, has_user_pref))
filter_engine_count++;
}
@@ -516,7 +543,9 @@ int results_handler(UrlParams *params) {
free(all_href);
for (int i = 0; i < ENGINE_COUNT; i++) {
- if (!ENGINE_REGISTRY[i].enabled)
+ if (!ENGINE_REGISTRY[i].enabled ||
+ !engine_allowed_for_user(&ENGINE_REGISTRY[i], user_engines,
+ user_engine_count, has_user_pref))
continue;
char *filter_href =
@@ -575,6 +604,11 @@ int results_handler(UrlParams *params) {
}
}
free(request_cache_key);
+ if (has_user_pref) {
+ for (int i = 0; i < user_engine_count; i++)
+ free(user_engines[i]);
+ free(user_engines);
+ }
free_context(&ctx);
if (redirect_url) {
send_redirect(redirect_url);
@@ -594,6 +628,11 @@ int results_handler(UrlParams *params) {
}
}
free(request_cache_key);
+ if (has_user_pref) {
+ for (int i = 0; i < user_engine_count; i++)
+ free(user_engines[i]);
+ free(user_engines);
+ }
free_context(&ctx);
char no_results_html[128];
snprintf(no_results_html, sizeof(no_results_html), "<h1>%s</h1>", no_results_msg);
@@ -696,6 +735,11 @@ int results_handler(UrlParams *params) {
}
}
free(request_cache_key);
+ if (has_user_pref) {
+ for (int i = 0; i < user_engine_count; i++)
+ free(user_engines[i]);
+ free(user_engines);
+ }
free_context(&ctx);
return 0;
}
@@ -822,6 +866,11 @@ int results_handler(UrlParams *params) {
}
}
free(locale);
+ if (has_user_pref) {
+ for (int i = 0; i < user_engine_count; i++)
+ free(user_engines[i]);
+ free(user_engines);
+ }
free_context(&ctx);
return 0;
diff --git a/src/Routes/Settings.c b/src/Routes/Settings.c
index cfadd09..1ad85a7 100644
--- a/src/Routes/Settings.c
+++ b/src/Routes/Settings.c
@@ -1,4 +1,5 @@
#include "Settings.h"
+#include "../Scraping/Scraping.h"
#include "../Utility/Utility.h"
#include <beaker.h>
#include <stdlib.h>
@@ -29,6 +30,48 @@ int settings_handler(UrlParams *params) {
inner_counts[i] = 2;
}
+ char **user_engines = NULL;
+ int user_engine_count = 0;
+ int has_user_pref = (get_user_engines(&user_engines, &user_engine_count) == 0);
+
+ int enabled_count = 0;
+ for (int i = 0; i < ENGINE_COUNT; i++) {
+ if (ENGINE_REGISTRY[i].enabled)
+ enabled_count++;
+ }
+
+ char ***engine_data = NULL;
+ int *engine_inner = NULL;
+
+ if (enabled_count > 0) {
+ engine_data = malloc(sizeof(char **) * enabled_count);
+ engine_inner = malloc(sizeof(int) * enabled_count);
+
+ int idx = 0;
+ for (int i = 0; i < ENGINE_COUNT; i++) {
+ if (!ENGINE_REGISTRY[i].enabled)
+ continue;
+
+ int is_selected = !has_user_pref;
+ if (has_user_pref) {
+ for (int j = 0; j < user_engine_count; j++) {
+ if (strcmp(user_engines[j], ENGINE_REGISTRY[i].id) == 0) {
+ is_selected = 1;
+ break;
+ }
+ }
+ }
+
+ engine_data[idx] = malloc(sizeof(char *) * 3);
+ engine_data[idx][0] = (char *)ENGINE_REGISTRY[i].id;
+ engine_data[idx][1] = (char *)ENGINE_REGISTRY[i].name;
+ engine_data[idx][2] = is_selected ? "checked" : "";
+ engine_inner[idx] = 3;
+
+ idx++;
+ }
+ }
+
TemplateContext ctx = new_context();
beaker_set_locale(&ctx, locale);
context_set(&ctx, "query", query);
@@ -36,9 +79,26 @@ int settings_handler(UrlParams *params) {
context_set(&ctx, "locale", locale);
context_set_array_of_arrays(&ctx, "locales", locale_data, locale_count, inner_counts);
+ if (enabled_count > 0) {
+ context_set_array_of_arrays(&ctx, "enabled_engines", engine_data,
+ enabled_count, engine_inner);
+ context_set(&ctx, "has_enabled_engines", "1");
+ }
+
for (int i = 0; i < locale_count; i++) {
free(locale_data[i]);
}
+ if (engine_data) {
+ for (int i = 0; i < enabled_count; i++)
+ free(engine_data[i]);
+ free(engine_data);
+ }
+ free(engine_inner);
+ if (has_user_pref) {
+ for (int i = 0; i < user_engine_count; i++)
+ free(user_engines[i]);
+ free(user_engines);
+ }
char *rendered_html = render_template("settings.html", &ctx);
send_response(rendered_html);
diff --git a/src/Routes/SettingsSave.c b/src/Routes/SettingsSave.c
index 323fe0d..cacff50 100644
--- a/src/Routes/SettingsSave.c
+++ b/src/Routes/SettingsSave.c
@@ -1,11 +1,18 @@
#include "SettingsSave.h"
+#include "../Scraping/Scraping.h"
+#include "../Utility/Utility.h"
#include <stdlib.h>
#include <string.h>
+#define MAX_ENGINE_IDS ENGINE_COUNT
+
int settings_save_handler(UrlParams *params) {
const char *theme = "";
const char *locale = "";
const char *query = "";
+ int engines_present = 0;
+ char selected_ids[ENGINE_COUNT][32];
+ int selected_count = 0;
if (params) {
for (int i = 0; i < params->count; i++) {
@@ -15,6 +22,19 @@ int settings_save_handler(UrlParams *params) {
locale = params->params[i].value;
} else if (strcmp(params->params[i].key, "q") == 0) {
query = params->params[i].value;
+ } else if (strcmp(params->params[i].key, "engines_present") == 0) {
+ engines_present = 1;
+ } else if (strncmp(params->params[i].key, "engine_", 7) == 0 &&
+ strcmp(params->params[i].value, "1") == 0) {
+ const char *engine_id = params->params[i].key + 7;
+ if (engine_id[0] != '\0' && is_engine_id_enabled(engine_id) &&
+ selected_count < ENGINE_COUNT) {
+ strncpy(selected_ids[selected_count], engine_id,
+ sizeof(selected_ids[selected_count]) - 1);
+ selected_ids[selected_count][sizeof(selected_ids[selected_count]) - 1] =
+ '\0';
+ selected_count++;
+ }
}
}
}
@@ -26,6 +46,18 @@ int settings_save_handler(UrlParams *params) {
set_cookie("locale", locale, "Fri, 31 Dec 2038 23:59:59 GMT", "/", false, false);
}
+ if (engines_present) {
+ char cookie_value[512];
+ cookie_value[0] = '\0';
+ for (int i = 0; i < selected_count; i++) {
+ if (i > 0)
+ strcat(cookie_value, ",");
+ strcat(cookie_value, selected_ids[i]);
+ }
+ set_cookie("engines", cookie_value, "Fri, 31 Dec 2038 23:59:59 GMT", "/",
+ false, false);
+ }
+
char redirect_url[512];
snprintf(redirect_url, sizeof(redirect_url), "/settings?q=%s", query);
send_redirect(redirect_url);
diff --git a/src/Utility/Utility.c b/src/Utility/Utility.c
index bffda4d..16656bb 100644
--- a/src/Utility/Utility.c
+++ b/src/Utility/Utility.c
@@ -1,4 +1,5 @@
#include "Utility.h"
+#include "../Scraping/Scraping.h"
#include <beaker.h>
#include <stdio.h>
#include <stdlib.h>
@@ -34,6 +35,89 @@ char *get_locale(const char *default_locale) {
return strdup(default_locale);
}
+static int engine_id_casecmp(const char *a, const char *b) {
+ while (*a && *b) {
+ char la = *a;
+ char lb = *b;
+ if (la >= 'A' && la <= 'Z') la = la - 'A' + 'a';
+ if (lb >= 'A' && lb <= 'Z') lb = lb - 'A' + 'a';
+ if (la != lb) return 0;
+ a++;
+ b++;
+ }
+ return *a == *b;
+}
+
+int is_engine_id_enabled(const char *engine_id) {
+ if (!engine_id) return 0;
+ for (int i = 0; i < ENGINE_COUNT; i++) {
+ if (ENGINE_REGISTRY[i].enabled &&
+ engine_id_casecmp(ENGINE_REGISTRY[i].id, engine_id)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int get_user_engines(char ***out_ids, int *out_count) {
+ *out_ids = NULL;
+ *out_count = 0;
+
+ char *cookie = get_cookie("engines");
+ if (!cookie || cookie[0] == '\0') {
+ free(cookie);
+ return -1;
+ }
+
+ char **ids = NULL;
+ int count = 0;
+
+ char *copy = strdup(cookie);
+ if (!copy) {
+ free(cookie);
+ return -1;
+ }
+
+ char *saveptr;
+ char *token = strtok_r(copy, ",", &saveptr);
+ while (token) {
+ while (*token == ' ' || *token == '\t')
+ token++;
+
+ if (token[0] != '\0' && is_engine_id_enabled(token)) {
+ char **new_ids = realloc(ids, sizeof(char *) * (count + 1));
+ if (new_ids) {
+ ids = new_ids;
+ ids[count] = strdup(token);
+ count++;
+ }
+ }
+
+ token = strtok_r(NULL, ",", &saveptr);
+ }
+
+ free(copy);
+ free(cookie);
+
+ if (count == 0) {
+ free(ids);
+ return -1;
+ }
+
+ *out_ids = ids;
+ *out_count = count;
+ return 0;
+}
+
+int user_engines_contains(const char *engine_id, char **ids, int count) {
+ if (!engine_id || !ids) return 0;
+ for (int i = 0; i < count; i++) {
+ if (engine_id_casecmp(ids[i], engine_id))
+ return 1;
+ }
+ return 0;
+}
+
int add_link_to_collection(const char *href, const char *label,
const char *class_name, char ****collection,
int **inner_counts, int current_count) {
diff --git a/src/Utility/Utility.h b/src/Utility/Utility.h
index 3863bc2..822c972 100644
--- a/src/Utility/Utility.h
+++ b/src/Utility/Utility.h
@@ -9,6 +9,10 @@ int hex_to_int(char c);
char *get_theme(const char *default_theme);
char *get_locale(const char *default_locale);
+int is_engine_id_enabled(const char *engine_id);
+int get_user_engines(char ***out_ids, int *out_count);
+int user_engines_contains(const char *engine_id, char **ids, int count);
+
int add_link_to_collection(const char *href, const char *label,
const char *class_name, char ****collection,
int **inner_counts, int current_count);