2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012-2013 - S/E - Sylvestre LEDRU
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
14 #define _GNU_SOURCE /* basename crashes this extension otherwise */
16 #include <curl/curl.h>
17 #include <libxml/uri.h>
19 #include "dlManager.h"
26 #include "charEncoding.h"
27 #include "localization.h"
29 /* ==================================================================== */
31 static char *Curl_basename(char *path);
32 #define basename(x) Curl_basename((x))
34 /* ==================================================================== */
35 static char errorBuffer[CURL_ERROR_SIZE];
36 /* ==================================================================== */
37 static int getProxyValues(char **proxyHost, long *proxyPort, char **proxyUserPwd);
38 /* ==================================================================== */
44 /* ==================================================================== */
45 static void init_string(struct inputString *s)
48 s->ptr = (char*)CALLOC(s->len + 1, sizeof(char));
51 Scierror(999, "Internal error: calloc() failed.\n");
56 /* ==================================================================== */
57 static size_t writefunc(void *ptr, size_t size, size_t nmemb, struct inputString *s)
59 size_t new_len = s->len + size * nmemb;
61 s->ptr = (char*)REALLOC(s->ptr, new_len + 1);
64 Scierror(999, "Internal error: realloc() failed.\n");
67 memcpy(s->ptr + s->len, ptr, size * nmemb);
68 s->ptr[new_len] = '\0';
73 /* ==================================================================== */
74 static char *getFileNameFromURL(char *url)
76 char *filename = NULL;
77 xmlURIPtr c = xmlParseURI(url);
81 Scierror(999, _("Could not parse the URL.\n"));
85 if (c->path == NULL || strcmp(c->path, "/") == 0)
87 filename = (char *)MALLOC((strlen(DEFAULT_FILENAME) + 1) * sizeof(char));
88 strcpy(filename, DEFAULT_FILENAME);
96 Scierror(43, "Internal error: c->path is null ?!\n");
98 strcpy(bname, basename(c->path));
99 filename = (char *)MALLOC((strlen(bname) + 1) * sizeof(char));
100 strcpy(filename, bname);
105 /* ==================================================================== */
106 int getProxyValues(char **proxyHost, long *proxyPort, char **proxyUserPwd)
116 char *host, *user, *password, *userpwd;
120 char *tp, *field, *value, *eqptr;
121 int eqpos = 0 , tplen;
123 //construct ATOMS config file path
124 configPtr = (char *)MALLOC(PATH_MAX * sizeof(char));
125 strcpy(configPtr, getSCIHOME());
127 osName = (char *)MALLOC(50 * sizeof(char));
128 strcpy(osName, getOSFullName());
129 if (strcmp(osName, "Windows") == 0)
131 char *osVer = (char *)MALLOC(50 * sizeof(char));
132 strcpy(osVer, getOSRelease());
133 if (strstr(osVer, "x64") != NULL)
135 strcat(configPtr, "/.atoms/x64/config");
139 strcat(configPtr, "/.atoms/config");
144 strcat(configPtr, "/.atoms/config");
148 wcfopen (pFile, configPtr , "rb" );
151 // Scierror(999,"Could not open scicurl_config file\n");
155 fseek (pFile , 0 , SEEK_END);
156 lSize = ftell(pFile);
159 // allocate memory to contain the whole file
160 buffer = (char*)MALLOC((lSize + 1) * sizeof(char));
165 buffer[lSize] = '\0';
167 // copy the file into the buffer
168 result = fread (buffer, 1, lSize, pFile);
171 Scierror(999, _("Failed to read the scicurl_config file '%s'.\n"), configPtr);
175 host = user = password = userpwd = NULL;
178 tp = field = value = eqptr = NULL;
181 // parse each line to extract variables
182 tp = strtok(buffer, "\n");
186 eqptr = strrchr(tp, '=');
187 tplen = (int)strlen(tp);
190 Scierror(999, _("Improper syntax of scicurl_config file ('%s'), '=' not found %d:%s\n"), configPtr, tplen, tp);
193 eqpos = (int)(eqptr - tp);
194 if (tplen <= eqpos + 1)
196 Scierror(999, _("Improper syntax of scicurl_config file ('%s'), after an '='\n"), configPtr);
199 if (tp[eqpos - 1] != ' ' || tp[eqpos + 1] != ' ')
201 Scierror(999, _("Improper syntax of scicurl_config file ('%s'), space before and after '=' expected\n"), configPtr);
205 //get field and value from each line
206 field = (char *)MALLOC(sizeof(char) * (eqpos));
207 value = (char *)MALLOC(sizeof(char) * (strlen(tp) - eqpos - 1));
209 memcpy(field, tp, eqpos - 1);
210 field[eqpos - 1] = '\0';
212 memcpy(value, tp + eqpos + 2, strlen(tp) - eqpos - 2);
213 value[strlen(tp) - eqpos - 2] = '\0';
216 //check and read proxy variables
217 if (strcmp(field, "useProxy") == 0)
219 if (strcmp(value, "False") == 0)
223 if (strcmp(value, "True") == 0)
228 else if (strcmp(field, "proxyHost") == 0)
230 host = (char *)MALLOC((strlen(value) + 1) * sizeof(char));
233 else if (strcmp(field, "proxyPort") == 0)
235 port = strtol(value, NULL, 10);
237 else if (strcmp(field, "proxyUser") == 0)
239 user = (char *)MALLOC((strlen(value) + 1) * sizeof(char));
242 else if (strcmp(field, "proxyPassword") == 0)
244 password = (char *)MALLOC((strlen(value) + 1) * sizeof(char));
245 strcpy(password, value);
251 tp = strtok(NULL, "\n");
254 // if proxy is set, update the parameters
258 // proxyUserPwd = "user:password"
259 int userlen, passlen;
260 userlen = passlen = 0;
263 userlen = (int)strlen(user);
265 if (password != NULL)
267 passlen = (int)strlen(user);
269 if (userlen + passlen != 0)
271 userpwd = (char *)MALLOC((userlen + passlen + 2) * sizeof(char));
272 strcpy(userpwd, user);
273 strcat(userpwd, ":");
274 if (password != NULL)
276 strcat(userpwd, password);
282 *proxyUserPwd = userpwd;
290 /* ==================================================================== */
291 char *downloadFile(char *url, char *dest, char *username, char *password, char **content)
295 char *filename = NULL;
297 curl = curl_easy_init();
303 struct inputString buffer;
305 init_string(&buffer);
307 res = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
310 Scierror(999, "Failed to set error buffer [%d]\n", res);
316 /* No second argument provided */
317 filename = getFileNameFromURL(url);
323 /* The target is a directory. Select the name from the URL */
324 char *name = getFileNameFromURL(url);
326 filename = (char *)MALLOC((strlen(name) + strlen("/") + strlen(dest) + 1) * sizeof(char));
327 strcpy(filename, dest);
328 strcat(filename, "/");
329 strcat(filename, name);
334 filename = (char *)MALLOC((strlen(dest) + 1) * sizeof(char));
335 strcpy(filename, dest);
339 wcfopen(file, (char*)filename, "wb");
343 Scierror(999, _("Failed opening '%s' for writing.\n"), filename);
347 res = curl_easy_setopt(curl, CURLOPT_URL, url);
350 Scierror(999, _("Failed to set URL [%s]\n"), errorBuffer);
354 //Set authentication variables
355 if (username != NULL)
358 int uplen = (int)strlen(username);
359 if (password != NULL)
361 uplen = uplen + (int)strlen(password);
364 userpass = (char *)MALLOC((uplen + 2) * sizeof(char));
366 strcpy(userpass, username);
367 strcat(userpass, ":");
368 if (password != NULL)
370 strcat(userpass, password);
373 res = curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
376 Scierror(999, "Failed to set httpauth type to ANY [%s]\n", errorBuffer);
379 res = curl_easy_setopt(curl, CURLOPT_USERPWD, userpass);
382 Scierror(999, _("Failed to set user:pwd [%s]\n"), errorBuffer);
385 } /* end authentication section */
388 //Set proxy variables
389 char *proxyHost = NULL;
390 char *proxyUserPwd = NULL;
391 long proxyPort = 1080;
394 proxySet = getProxyValues(&proxyHost, &proxyPort, &proxyUserPwd);
398 res = curl_easy_setopt(curl, CURLOPT_PROXY, proxyHost);
401 Scierror(999, _("Failed to set proxy host [%s]\n"), errorBuffer);
404 curl_easy_setopt(curl, CURLOPT_PROXYPORT, proxyPort);
407 Scierror(999, _("Failed to set proxy port [%s]\n"), errorBuffer);
410 if (proxyUserPwd != NULL)
412 res = curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, proxyUserPwd);
415 Scierror(999, _("Failed to set proxy user:password [%s]\n"), errorBuffer);
421 } /* end of the set of the proxy */
423 res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
427 Scierror(999, _("Failed to set write function [%s]\n"), errorBuffer);
431 //Get data to be written to the variable
432 res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
435 Scierror(999, _("Failed to set write data [%s]\n"), errorBuffer);
440 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
442 res = curl_easy_perform(curl);
446 Scierror(999, _("Transfer did not complete successfully: %s\n"), errorBuffer);
451 fwrite(buffer.ptr, sizeof(char), buffer.len, file);
453 /* Create the variable which contains the output argument */
454 *content = buffer.ptr;
457 curl_easy_cleanup(curl);
465 Scierror(999, "Failed opening the curl handle.\n");
470 /* ==================================================================== */
471 static char *Curl_basename(char *path)
476 s1 = strrchr(path, '/');
477 s2 = strrchr(path, '\\');
481 path = (s1 > s2 ? s1 : s2) + 1;
493 /* ==================================================================== */