get.c (4327B)
1 /* get.c - download and save hosts entries from URL sources 2 * 3 * headers and macros */ 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <curl/curl.h> 8 #include <ctype.h> 9 10 #include "get.h" 11 #include "hfc.h" 12 13 #define HOSTS_FILE_PATH "/etc/hosts" 14 15 struct MemoryStruct { 16 char *memory; 17 size_t size; 18 }; 19 20 static size_t 21 WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) 22 { 23 size_t realsize; 24 char *ptr; 25 struct MemoryStruct *mem; 26 27 realsize = size * nmemb; 28 mem = (struct MemoryStruct *)userp; 29 30 ptr = realloc(mem->memory, mem->size + realsize + 1); 31 if (!ptr) 32 return 0; 33 34 mem->memory = ptr; 35 memcpy(&(mem->memory[mem->size]), contents, realsize); 36 mem->size += realsize; 37 mem->memory[mem->size] = '\0'; 38 39 return realsize; 40 } 41 42 char * 43 download_url(const char *url, char *error_msg, size_t err_size) 44 { 45 CURL *curl_handle; 46 CURLcode res; 47 struct MemoryStruct chunk; 48 49 chunk.memory = malloc(1); 50 chunk.size = 0; 51 52 curl_handle = curl_easy_init(); 53 if (!curl_handle) { 54 snprintf(error_msg, err_size, "Could not initialize CURL"); 55 free(chunk.memory); 56 return NULL; 57 } 58 59 char user_agent[64]; 60 snprintf(user_agent, sizeof(user_agent), "hfc/%s", HFC_VERSION); 61 62 curl_easy_setopt(curl_handle, CURLOPT_URL, url); 63 curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); 64 curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); 65 curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, user_agent); 66 curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, error_msg); 67 curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 0L); 68 69 res = curl_easy_perform(curl_handle); 70 if (res != CURLE_OK) { 71 free(chunk.memory); 72 chunk.memory = NULL; 73 } else { 74 error_msg[0] = '\0'; 75 } 76 77 curl_easy_cleanup(curl_handle); 78 return chunk.memory; 79 } 80 81 long 82 get_remote_content_length(const char *url) 83 { 84 CURL *curl; 85 CURLcode res; 86 curl_off_t clength = -1; 87 88 curl = curl_easy_init(); 89 if (!curl) 90 return -1; 91 92 char user_agent[64]; 93 snprintf(user_agent, sizeof(user_agent), "hfc/%s", HFC_VERSION); 94 curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent); 95 curl_easy_setopt(curl, CURLOPT_URL, url); 96 curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); 97 curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); 98 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); 99 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); 100 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L); 101 102 res = curl_easy_perform(curl); 103 if (res == CURLE_OK) { 104 if (curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &clength) != CURLE_OK) 105 clength = -1; 106 } 107 108 curl_easy_cleanup(curl); 109 return (clength >= 0) ? (long)clength : -1; 110 } 111 112 int 113 contains_valid_hosts_entry(const char *content) 114 { 115 const char *line, *next_line; 116 size_t len; 117 char *cr; 118 char buffer[512]; 119 120 if (!content) 121 return 0; 122 123 line = content; 124 while (*line) { 125 next_line = strchr(line, '\n'); 126 len = next_line ? (size_t)(next_line - line) : strlen(line); 127 128 if (len >= sizeof(buffer)) 129 len = sizeof(buffer) - 1; 130 131 if (len > 0) { 132 memcpy(buffer, line, len); 133 buffer[len] = '\0'; 134 135 cr = strchr(buffer, '\r'); 136 if (cr) 137 *cr = '\0'; 138 139 while (*buffer == ' ' || *buffer == '\t') 140 memmove(buffer, buffer + 1, strlen(buffer)); 141 142 if (strncmp(buffer, "0.0.0.0 ", 8) == 0 || 143 strncmp(buffer, "127.0.0.1 ", 10) == 0) 144 return 1; 145 } 146 147 if (!next_line) 148 break; 149 line = next_line + 1; 150 } 151 152 return 0; 153 } 154 155 int 156 save_to_hosts_file(const char *content, const char *url, int number) 157 { 158 FILE *fp; 159 const char *line, *next_line; 160 size_t len; 161 char *cr; 162 char buffer[512], ip[16], domain[256]; 163 164 if (!content) 165 return 0; 166 167 fp = fopen(HOSTS_FILE_PATH, "a"); 168 if (!fp) 169 return 0; 170 171 fprintf(fp, "# %d. %s\n", number, url); 172 173 line = content; 174 while (*line) { 175 next_line = strchr(line, '\n'); 176 len = next_line ? (size_t)(next_line - line) : strlen(line); 177 178 if (len >= sizeof(buffer)) 179 len = sizeof(buffer) - 1; 180 181 if (len > 0) { 182 memcpy(buffer, line, len); 183 buffer[len] = '\0'; 184 185 cr = strchr(buffer, '\r'); 186 if (cr) 187 *cr = '\0'; 188 189 while (*buffer == ' ' || *buffer == '\t') 190 memmove(buffer, buffer + 1, strlen(buffer)); 191 192 if (sscanf(buffer, "%15s %255s", ip, domain) == 2) { 193 if (!strcmp(ip, "127.0.0.1") || !strcmp(ip, "0.0.0.0")) 194 fprintf(fp, "0.0.0.0 %s\n", domain); 195 } 196 } 197 198 if (!next_line) 199 break; 200 line = next_line + 1; 201 } 202 203 fclose(fp); 204 return 1; 205 }