/* This file is part of libravatarserv. * Copyright © 2018 tastytea * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include // getenv() #include #include "libravatarserv.hpp" using std::cout; using std::cerr; using std::endl; using global::avatar_dir; // Global variables std::map hash::table; fs::path global::avatar_dir = ""; int main() { const char *tmp = std::getenv("REQUEST_URI"); if (tmp == nullptr) { cout << "Status: 404 Not Found\n\n"; cerr << "Error: ${REQUEST_URI} is empty.\n"; return 1; } const string request = tmp; if (!find_avatar_dir()) { cout << "Status: 404 Not Found\n\n"; cerr << "Error: No avatars found.\n"; return 3; } hash::fill_table(); if (request.substr(0, 8) != "/avatar/" || request.find('/', 8) != std::string::npos) { cout << "Status: 404 Not Found\n\n"; cerr << "Error: Invalid URL.\n"; return 1; } cout << "Content-type: image/png\n\n"; cout.flush(); // We need to flush before we use /dev/stdout directly. uint16_t size = 80; string digest = request.substr(8); std::transform(digest.begin(), digest.end(), digest.begin(), ::tolower); std::size_t pos_digest = digest.find('?'); if (pos_digest != std::string::npos) { std::size_t pos_size = digest.find("s=", pos_digest); if (pos_size != std::string::npos) { size = static_cast(std::stoul(digest.substr(pos_size + 2))); } digest = digest.substr(0, pos_digest); } image::Image answer = image::get(digest, size); if (answer.error == 0) { // answer.image.write("test.png"); answer.image.write("/dev/stdout"); } else { cerr << "Error " << std::to_string(answer.error) << ": Could not open file.\n"; } return 0; } bool find_avatar_dir() { const char *envdir = std::getenv("AVATAR_DIR"); if (envdir != nullptr) { if (fs::is_directory(envdir)) { avatar_dir = envdir; } else { return false; } } else { xdgHandle xdg; xdgInitHandle(&xdg); auto data_dirs = xdgDataDirectories(&xdg); const uint8_t size = sizeof(data_dirs) / sizeof(*data_dirs); for (uint8_t index = 0; index <= size; ++index) { const string searchdir = data_dirs[index] + string("/libravatarserv"); if (fs::is_directory(searchdir)) { avatar_dir = searchdir; break; } } xdgWipeHandle(&xdg); if (avatar_dir.empty()) { return false; } } return true; }