107 lines
2.8 KiB
C
107 lines
2.8 KiB
C
/*
|
|
* Copyright (c) 2023 Emma Tebibyte
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify it under
|
|
* the terms of the GNU Affero General Public License as published by the Free
|
|
* Software Foundation, either version 3 of the License, or (at your option) any
|
|
* later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sysexits.h>
|
|
#include <curl/curl.h>
|
|
#include <jansson.h>
|
|
|
|
#define SEARX_QUERY_JSON "search?format=json&q="
|
|
|
|
typedef struct curl_read_data_t {
|
|
size_t len;
|
|
char* data;
|
|
} curl_read_data_t;
|
|
|
|
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) {
|
|
curl_read_data_t *data = (curl_read_data_t *)userp;
|
|
size_t old_len;
|
|
|
|
if (data->len == 0) {
|
|
data->len = nmemb;
|
|
data->data = (char *) malloc(nmemb);
|
|
memcpy(data->data, buffer, nmemb);
|
|
} else {
|
|
old_len = data->len;
|
|
data->len += nmemb;
|
|
data->data = (char *) realloc(data->data, data->len);
|
|
memcpy(data->data + old_len, buffer, nmemb);
|
|
}
|
|
|
|
return nmemb;
|
|
}
|
|
|
|
curl_read_data_t search(char *argv[], char *term) {
|
|
char *url = "https://searx.mxchange.org/";
|
|
size_t buf_size = sizeof(SEARX_QUERY_JSON) + strlen(url) + strlen(term);
|
|
char *search_url = malloc(buf_size);
|
|
char *error;
|
|
CURL *handle;
|
|
CURLcode res;
|
|
|
|
snprintf(search_url, buf_size, "%s%s%s", url, SEARX_QUERY_JSON, term);
|
|
|
|
curl_read_data_t json;
|
|
json.len = 0;
|
|
json.data = NULL;
|
|
|
|
handle = curl_easy_init();
|
|
|
|
if (handle) {
|
|
error[CURL_ERROR_SIZE];
|
|
curl_easy_setopt(handle, CURLOPT_URL, search_url);
|
|
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_data);
|
|
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &json);
|
|
curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, error);
|
|
res = curl_easy_perform(handle);
|
|
curl_easy_cleanup(handle);
|
|
fprintf(stderr, "%s: %s", argv[0], error);
|
|
} else {
|
|
fprintf(stderr, "%s: failed to initialize curl.\n");
|
|
}
|
|
|
|
return json;
|
|
}
|
|
|
|
void parse_json(char *argv[], char* json) {
|
|
int out;
|
|
json_error_t *error;
|
|
json_t *json_val = json_loads(json, JSON_DECODE_ANY, error);
|
|
|
|
out = json_unpack(json_val, "{s:o}");
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
curl_read_data_t json;
|
|
|
|
if (argc < 1) {
|
|
fprintf(stderr, "Usage: %s terms...", argv[0]);
|
|
return EX_USAGE;
|
|
}
|
|
|
|
for (int i = 1; i < argc; i++) {
|
|
json = search(argv, argv[i]);
|
|
write(1, json.data, json.len);
|
|
parse_json(argv, json.data);
|
|
}
|
|
return EX_OK;
|
|
}
|