/* * 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 #include #include #include #include #include #include #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) { char *parsed_json; json_error_t *error; char *pretty_print; json_t *json_val = json_loads(json, JSON_DECODE_ANY, error); json_unpack(json_val, "{s:o}", parsed_json); pretty_print = json_dumps(json_val, JSON_INDENT(2)); printf("%s\n", pretty_print); } 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]); parse_json(argv, json.data); } return EX_OK; }