示例#1
0
static gchar *
decode_url(const gchar *url)
{
	int col = 0;
	int row;
	int x;
	int len;
	int i, j, k;
	gchar *array;
	gchar *decode_url = NULL;
	gchar *p;

	if (url == NULL)
		return NULL;

	row = *url - '0';
	len = strlen(url + 1);
	col = len / row;
	x = len % row;

	if (x != 0)
	col += 1;

	array = (char *)calloc(len + sizeof(char), sizeof(char));

	k = 1;
	for(i=0; i<row; i++)
	{
		for(j=0; j<col; j++, k++)
			array[i + row * j] = url[k];

		if (x > 0)
		{
			x--;
			if(x == 0)
			 col -= 1;
		}
	}

	decode_url = curl_easy_unescape(NULL, array, 0, NULL);
	p = decode_url;

	while(*p)
	{
		if (*p == '^')
			*p = '0';
		p++;
	}
	free(array);

	return decode_url;
}
示例#2
0
cString cSatipRtsp::RtspUnescapeString(const char *strP)
{
  debug1("%s (%s) [device %d]", __PRETTY_FUNCTION__, strP, tunerM.GetId());
  if (handleM) {
     char *p = curl_easy_unescape(handleM, strP, 0, NULL);
     cString s = p;
     curl_free(p);

     return s;
     }

  return cString(strP);
}
示例#3
0
文件: pop3.c 项目: sherpya/naitool
/***********************************************************************
 *
 * pop3_parse_url_path()
 *
 * Parse the URL path into separate path components.
 *
 */
static CURLcode pop3_parse_url_path(struct connectdata *conn)
{
  /* the pop3 struct is already inited in pop3_connect() */
  struct pop3_conn *pop3c = &conn->proto.pop3c;
  struct SessionHandle *data = conn->data;
  const char *path = data->state.path;
  int len;

  /* url decode the path and use this mailbox */
  pop3c->mailbox = curl_easy_unescape(data, path, 0, &len);

  return CURLE_OK;
}
示例#4
0
/*
 * Unescape the LDAP-URL components
 */
static bool unescape_elements(void *data, LDAPURLDesc *ludp)
{
    int i;

    if (ludp->lud_filter)
    {
        ludp->lud_filter = curl_easy_unescape(data, ludp->lud_filter, 0, NULL);
        if (!ludp->lud_filter)
            return (FALSE);
    }

    for (i = 0; ludp->lud_attrs && ludp->lud_attrs[i]; i++)
    {
        ludp->lud_attrs[i] = curl_easy_unescape(data, ludp->lud_attrs[i], 0, NULL);
        if (!ludp->lud_attrs[i])
            return (FALSE);
    }

    for (i = 0; ludp->lud_exts && ludp->lud_exts[i]; i++)
    {
        ludp->lud_exts[i] = curl_easy_unescape(data, ludp->lud_exts[i], 0, NULL);
        if (!ludp->lud_exts[i])
            return (FALSE);
    }

    if (ludp->lud_dn)
    {
        char *dn     = ludp->lud_dn;
        char *new_dn = curl_easy_unescape(data, dn, 0, NULL);

        free(dn);
        ludp->lud_dn = new_dn;
        if (!new_dn)
            return (FALSE);
    }

    return (TRUE);
}
示例#5
0
std::string curl::unescape(const std::string& encoded)
{
    int len = 0;
    char* rstr = curl_easy_unescape(m_curl, encoded.c_str(), encoded.size(), &len);

    if (!rstr)
    {
        throw std::bad_alloc();
    }

    boost::shared_ptr<char> str(rstr, curl_free);

    return std::string(str.get(), static_cast<size_t>(len));
}
示例#6
0
char* LmcCom::unescape(char* buf)
{
   int len = 0;
   char* res;

   res = curl_easy_unescape(curl , buf, strlen(buf), &len);

   if (res)
      strcpy(buf, res);

   free(res);

   return buf;
}
int main()
{
	CURL *curl = curl_easy_init( );

	printf("Content-Type: text/html;charset=us-ascii\n\n");
	char *q = getenv("QUERY_STRING");
	if(q == NULL || strlen(q) <= 0)
	{
		printf("<p>You must pass in some source code.</p>");
		return 1;
	}
	if(strlen(q) > 1024)
	{
		printf("<p>The source code is too long.</p>");
		return 1;
	}

	q = curl_easy_unescape(curl, q, strlen(q), NULL);

	FILE * log = fopen(HOME "/tmp/build.log", "w+");
	char * filename = tempnam("/tmp", "gcc_");
	fprintf(log, "%d IP: %s Output: %s\n", time(0), getenv("REMOTE_ADDR"), filename);
	fflush(log);
	
	chdir(HOME "/root");
	chroot(HOME "/root");

	struct passwd *passwd = getpwnam(USER);
	if(passwd == NULL)
	{
		printf("<p>User does not exist.</p>");
		return 1;
	}

	if(setuid(passwd->pw_uid) < 0)
		return 1;

	char buffer[2048];
	sprintf(buffer, "echo -n '%s' | gcc -x c -o %s -", q, filename);

	printf("Starting build...\n");

	int pid = safe_system(buffer);
	
	fprintf(log, "%d %s done.\n", time(0), filename);
	fclose(log);

	sleep_kill(pid);
	return 0;
}
bool YoutubeCrawler::getMaxQualityURI(CURL *handle, std::string &content, std::vector<std::string> &results){
	size_t startPos = content.find("url_encoded_fmt_stream_map=");
	if(startPos == std::string::npos){
		return false;
	}
	startPos += 27;
	size_t endPos = content.find("&amp;", startPos);
	if(endPos == std::string::npos){
		endPos = content.find("\"", startPos);
		if(endPos == std::string::npos){
			return false;
		}
	}
	int cstringLen = 0;
	char *decodeContent = curl_easy_unescape(handle, content.c_str() + startPos, endPos - startPos, &cstringLen);
	content.assign(decodeContent, cstringLen);
	curl_free(decodeContent);
	startPos = content.find("url=");
	std::string tmpURI;
	while(startPos != std::string::npos){
		startPos += 4;
		endPos = content.find(",", startPos);
		if(endPos == std::string::npos){
			endPos = content.size();
		}
		decodeContent = curl_easy_unescape(handle, content.c_str() + startPos, endPos - startPos, &cstringLen);
		tmpURI.assign(decodeContent, cstringLen);
		tmpURI = tmpURI.substr(0, tmpURI.find(";"));
		curl_free(decodeContent);
		results.push_back(tmpURI);
		startPos = content.find("url=", endPos + 1);
	}
	if(results.size() == 0){
		return false;
	}
	return true;
}
示例#9
0
文件: session_ext.c 项目: tmm1/patron
// Unescapes the provided string.
VALUE session_unescape(VALUE self, VALUE value) {
  struct curl_state *state;
  Data_Get_Struct(self, struct curl_state, state);

  VALUE string = StringValue(value);
  char* unescaped = curl_easy_unescape(state->handle,
                                       RSTRING_PTR(string),
                                       RSTRING_LEN(string),
                                       NULL);

  VALUE retval = rb_str_new2(unescaped);
  curl_free(unescaped);

  return retval;
}
示例#10
0
/*
 * Unescapes the provided string using libCURL URL escaping functions.
 *
 * @param [String] value URL-encoded String to unescape
*  @return [String] unescaped (decoded) string
 */
static VALUE session_unescape(VALUE self, VALUE value) {
  VALUE string = StringValue(value);
  char* unescaped = NULL;
  VALUE retval = Qnil;

  struct curl_state* state = curl_easy_init();
  unescaped = curl_easy_unescape(state->handle,
                                 RSTRING_PTR(string),
                                 (int) RSTRING_LEN(string),
                                 NULL);

  retval = rb_str_new2(unescaped);
  curl_free(unescaped);
  curl_easy_cleanup(state);

  return retval;
}
示例#11
0
char* SogouParsePinyin(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue)
{
    char *start = NULL, *end = NULL;
    if ((start = strchr(queue->str, '"')) != NULL && (end = strstr(queue->str, "%EF%BC%9A")) != NULL)
    {
        start ++;
        if (start < end)
        {
            size_t length = end - start;
            int conv_length;
            char *unescapedstring = curl_easy_unescape(queue->curl, start, length, &conv_length);
            char *realstring = strdup(unescapedstring);
            curl_free(unescapedstring);
            return realstring;
        }
    }
    return NULL;
}
示例#12
0
文件: imap.c 项目: 1833183060/wke
/***********************************************************************
 *
 * imap_parse_url_path()
 *
 * Parse the URL path into separate path components.
 *
 */
static CURLcode imap_parse_url_path(struct connectdata *conn)
{
  /* the imap struct is already inited in imap_connect() */
  struct imap_conn *imapc = &conn->proto.imapc;
  struct SessionHandle *data = conn->data;
  const char *path = data->state.path;
  int len;

  if(!*path)
    path = "INBOX";

  /* url decode the path and use this mailbox */
  imapc->mailbox = curl_easy_unescape(data, path, 0, &len);
  if(!imapc->mailbox)
    return CURLE_OUT_OF_MEMORY;

  return CURLE_OK;
}
示例#13
0
	/**
	 * Decodes a URL encoded string and returns it.
	 * @param QString input
	 * @returns QString
	 * @author John M. Harris, Jr.
	 */
	QString HttpService::UrlDecode(QString input){
		CURL* curl;

		curl = curl_easy_init();
		if(curl){
			char* encoded = curl_easy_unescape(curl, input.toStdString().c_str(), 0, NULL);

			size_t thingLen = strlen(encoded) + 1;
			char* newGuy = new char[thingLen];
			strcpy(newGuy, encoded);
			//newGuy[thingLen] = '\0';

			curl_free(encoded);
			curl_easy_cleanup(curl);

			return QString(newGuy);
		}
		return "";
	}
示例#14
0
文件: http-api.c 项目: tanec/fcache
// out should be enough to hold result
bool
http_unescape(const char *in, char *out)
{
    int   len = -1;
    char *res = NULL;
    CURL *curl;
    bool ret = false;

    curl = curl_easy_init();
    if (curl != NULL) {
        res = curl_easy_unescape(curl, in, 0, &len);
        if (res != NULL && len > 0) {
            memcpy(out, res, len+1);
            ret = true;
        }
        if (res != NULL) curl_free(res);
        curl_easy_cleanup(curl);
        return ret;
    }
    return false;
}
示例#15
0
static char* unescape_word(struct SessionHandle *data, const char *inputbuff)
{
    char *newp;
    char *dictp;
    char *ptr;
    int  len;
    char byte;
    int  olen = 0;

    newp = curl_easy_unescape(data, inputbuff, 0, &len);
    if (!newp)
        return NULL;

    dictp = malloc(((size_t)len) * 2 + 1); /* add one for terminating zero */
    if (dictp)
    {
        /* According to RFC2229 section 2.2, these letters need to be escaped with
         \[letter] */
        for (ptr = newp;
             (byte = *ptr) != 0;
             ptr++)
        {
            if ((byte <= 32) || (byte == 127) ||
                (byte == '\'') || (byte == '\"') || (byte == '\\'))
            {
                dictp[olen++] = '\\';
            }

            dictp[olen++] = byte;
        }

        dictp[olen] = 0;

        free(newp);
    }

    return dictp;
}
示例#16
0
char *url_to_path(const char *url)
{
	char *tmps, *unesc;
	CURL *curl;

	tmps = strstr(url, "///localhost/") + 13;

	if(tmps < url) tmps = strstr(url,"///") + 3;

	if(tmps >= url)
	{
		if(curl = curl_easy_init())
		{
			unesc = curl_easy_unescape(curl,tmps,0,NULL);
			tmps = strdup(unesc);
			curl_free(unesc);
			curl_easy_cleanup(curl);
			return tmps;
		}
	}

	return strdup((char *)url);
}
示例#17
0
文件: curl.c 项目: NgoHuy/uim
static void *
uim_curl_url_unescape_internal(void *url_)
{
  uim_lisp unescaped_url_;
  const char *escaped_url = REFER_C_STR((uim_lisp)url_);
  char *unescaped_url;
  int len; /* curl_easy_unescape uses int, not size_t */
  CURL *curl;

  curl = curl_easy_init();

  if(curl == NULL)
    return uim_scm_f();

  unescaped_url = curl_easy_unescape(curl, escaped_url,
				     strlen(escaped_url), &len);
  unescaped_url_ = (len > 0) ? MAKE_STR(unescaped_url) : uim_scm_f();

  curl_free(unescaped_url);
  curl_easy_cleanup(curl);
  curl_global_cleanup();

  return (void *)unescaped_url_;
}
示例#18
0
文件: wswcurl.c 项目: ewirch/qfusion
size_t wswcurl_urldecode( const char *src, char *dst, size_t size )
{
	int unesc_len;
	char *curl_unesc;

	assert( src );
	assert( dst );

	if( !src || !dst ) {
		return 0;
	}

	// libcurl needs a curl pointer to be passed to a function that
	// should clearly be "static", how inconvenient...
	if( !curldummy ) {
		curldummy = curl_easy_init();
	}

	curl_unesc = curl_easy_unescape( curldummy, src, 0, &unesc_len );
	Q_strncpyz( dst, curl_unesc, size );
	curl_free( curl_unesc );

	return (size_t)unesc_len;
}
示例#19
0
/*
 * smtp_connect() should do everything that is to be considered a part of
 * the connection phase.
 *
 * The variable 'done' points to will be TRUE if the protocol-layer connect
 * phase is done when this function returns, or FALSE is not. When called as
 * a part of the easy interface, it will always be TRUE.
 */
static CURLcode smtp_connect(struct connectdata *conn,
                             bool *done) /* see description above */
{
    CURLcode result;
    struct smtp_conn *smtpc = &conn->proto.smtpc;
    struct SessionHandle *data=conn->data;
    struct pingpong *pp=&smtpc->pp;
    const char *path = conn->data->state.path;
    int len;
    char localhost[1024 + 1];

    *done = FALSE; /* default to not done yet */

    /* If there already is a protocol-specific struct allocated for this
       sessionhandle, deal with it */
    Curl_reset_reqproto(conn);

    result = smtp_init(conn);
    if(CURLE_OK != result)
        return result;

    /* We always support persistant connections on smtp */
    conn->bits.close = FALSE;

    pp->response_time = RESP_TIMEOUT; /* set default response time-out */
    pp->statemach_act = smtp_statemach_act;
    pp->endofresp = smtp_endofresp;
    pp->conn = conn;

#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_PROXY)
    if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
        /* for SMTP over HTTP proxy */
        struct HTTP http_proxy;
        struct FTP *smtp_save;

        /* BLOCKING */
        /* We want "seamless" SMTP operations through HTTP proxy tunnel */

        /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member
         * conn->proto.http; we want SMTP through HTTP and we have to change the
         * member temporarily for connecting to the HTTP proxy. After
         * Curl_proxyCONNECT we have to set back the member to the original struct
         * SMTP pointer
         */
        smtp_save = data->state.proto.smtp;
        memset(&http_proxy, 0, sizeof(http_proxy));
        data->state.proto.http = &http_proxy;

        result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
                                   conn->host.name, conn->remote_port);

        data->state.proto.smtp = smtp_save;

        if(CURLE_OK != result)
            return result;
    }
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */

    if(conn->protocol & PROT_SMTPS) {
        /* BLOCKING */
        /* SMTPS is simply smtp with SSL for the control channel */
        /* now, perform the SSL initialization for this socket */
        result = Curl_ssl_connect(conn, FIRSTSOCKET);
        if(result)
            return result;
    }

    Curl_pp_init(pp); /* init the response reader stuff */

    pp->response_time = RESP_TIMEOUT; /* set default response time-out */
    pp->statemach_act = smtp_statemach_act;
    pp->endofresp = smtp_endofresp;
    pp->conn = conn;

    if(!*path) {
        if(!Curl_gethostname(localhost, sizeof localhost))
            path = localhost;
        else
            path = "localhost";
    }

    /* url decode the path and use it as domain with EHLO */
    smtpc->domain = curl_easy_unescape(conn->data, path, 0, &len);
    if(!smtpc->domain)
        return CURLE_OUT_OF_MEMORY;

    /* When we connect, we start in the state where we await the server greeting
     */
    state(conn, SMTP_SERVERGREET);

    if(data->state.used_interface == Curl_if_multi)
        result = smtp_multi_statemach(conn, done);
    else {
        result = smtp_easy_statemach(conn);
        if(!result)
            *done = TRUE;
    }

    return result;
}
示例#20
0
文件: file.c 项目: 0w/moai-dev
/*
 * file_connect() gets called from Curl_protocol_connect() to allow us to
 * do protocol-specific actions at connect-time.  We emulate a
 * connect-then-transfer protocol and "connect" to the file here
 */
static CURLcode file_connect(struct connectdata *conn, bool *done)
{
  struct SessionHandle *data = conn->data;
  char *real_path = curl_easy_unescape(data, data->state.path, 0, NULL);
  struct FILEPROTO *file;
  int fd;
#ifdef DOS_FILESYSTEM
  int i;
  char *actual_path;
#endif

  if(!real_path)
    return CURLE_OUT_OF_MEMORY;

  /* If there already is a protocol-specific struct allocated for this
     sessionhandle, deal with it */
  Curl_reset_reqproto(conn);

  if(!data->state.proto.file) {
    file = calloc(sizeof(struct FILEPROTO), 1);
    if(!file) {
      free(real_path);
      return CURLE_OUT_OF_MEMORY;
    }
    data->state.proto.file = file;
  }
  else {
    /* file is not a protocol that can deal with "persistancy" */
    file = data->state.proto.file;
    Curl_safefree(file->freepath);
    if(file->fd != -1)
      close(file->fd);
    file->path = NULL;
    file->freepath = NULL;
    file->fd = -1;
  }

#ifdef DOS_FILESYSTEM
  /* If the first character is a slash, and there's
     something that looks like a drive at the beginning of
     the path, skip the slash.  If we remove the initial
     slash in all cases, paths without drive letters end up
     relative to the current directory which isn't how
     browsers work.

     Some browsers accept | instead of : as the drive letter
     separator, so we do too.

     On other platforms, we need the slash to indicate an
     absolute pathname.  On Windows, absolute paths start
     with a drive letter.
  */
  actual_path = real_path;
  if((actual_path[0] == '/') &&
      actual_path[1] &&
      (actual_path[2] == ':' || actual_path[2] == '|'))
  {
    actual_path[2] = ':';
    actual_path++;
  }

  /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
  for (i=0; actual_path[i] != '\0'; ++i)
    if(actual_path[i] == '/')
      actual_path[i] = '\\';

  fd = open_readonly(actual_path, O_RDONLY|O_BINARY); /* no CR/LF translation */
  file->path = actual_path;
#else
  fd = open_readonly(real_path, O_RDONLY);
  file->path = real_path;
#endif
  file->freepath = real_path; /* free this when done */

  file->fd = fd;
  if(!data->set.upload && (fd == -1)) {
    failf(data, "Couldn't open file %s", data->state.path);
    file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
    return CURLE_FILE_COULDNT_READ_FILE;
  }
  *done = TRUE;

  return CURLE_OK;
}
示例#21
0
static void handle_messages(viprinet_status_t *status)
{
    int len, sep, i;
    char *line, *param;
    char type;
    char id[VIPRINET_MAX_STRING_LEN];
    char value[VIPRINET_MAX_STRING_LEN];
    viprinet_status_id_t id_i;
    char *unencoded;

    len = strlen(status->buffer);
    line = strtok(status->buffer, "\r\n");
    while (line != NULL) {
        type = line[0];
        param = &(line[2]);
        
        if (type == 'N' || type == 'V' || type == 'I') {
            sep = strcspn(param, " ");
            strncpy(id, param, sep);
            strncpy(value, &(param[sep+1]), VIPRINET_MAX_STRING_LEN);
            id_i = (viprinet_status_id_t)atol(id);
            switch(type) {
                case 'N':
                    if (status->new_path_event) {
                        for (i = 0; i < strlen(value); i++) {
                            if (value[i] == '+') {
                                value[i] = ' ';
                            }
                        }
                        unencoded = curl_easy_unescape(status->curl, value, 0, NULL);
                        (*status->new_path_event)(id_i, unencoded, status->data);
                        curl_free(unencoded);
                    }
                    break;
                case 'V':
                    if (status->update_value_event) {
                        (*status->update_value_event)(id_i, (viprinet_status_value_t)atol(value), status->data);
                    }
                    break;
                case 'I':
                    if (status->update_info_event) {
                        (*status->update_info_event)(id_i, value, status->data);
                    }
                    break;
                default:
                    /* DO NOTHING */
#                   ifdef DEBUG
                    printf("UNKNWON MESSAGE '%s'\n", param);
#                   endif
                    break;
            }
#           ifdef DEBUG
            printf("Type='%c';ID='%s';Value='%s'\n", type, id, value);
#           endif
        } else if (type == 'D') {
            if (status->delete_path_event) {
                for (i = 0; i < strlen(value); i++) {
                    if (value[i] == '+') {
                        value[i] = ' ';
                    }
                }
                unencoded = curl_easy_unescape(status->curl, value, 0, NULL);
                (*status->delete_path_event)(unencoded, status->data);
                curl_free(unencoded);
            }
#           ifdef DEBUG
            printf("Type='%c';Value='%s'\n", type, param);
#           endif
        } else {
#           ifdef DEBUG
            printf("UNKNOWN MESSAGE '%s'\n", param);
#           endif
        }
        line = strtok(NULL, "\r\n");
    }
}
示例#22
0
int test(char *URL)
{
  const unsigned char a[] = {0x2f, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
                             0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe6, 0xf7};
  CURLcode res = CURLE_OK;
  char *ptr = NULL;
  int asize;
  int outlen;
  char *raw;

  (void)URL; /* we don't use this */

  if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    fprintf(stderr, "curl_global_init() failed\n");
    return TEST_ERR_MAJOR_BAD;
  }

  asize = (int)sizeof(a);
  ptr = curl_easy_escape(NULL, (char *)a, asize);
  printf("%s\n", ptr);
  if(ptr)
    curl_free(ptr);

  /* deprecated API */
  ptr = curl_escape((char *)a, asize);
  printf("%s\n", ptr);
  if(!ptr) {
    res = TEST_ERR_MAJOR_BAD;
    goto test_cleanup;
  }

  raw = curl_easy_unescape(NULL, ptr, (int)strlen(ptr), &outlen);
  printf("outlen == %d\n", outlen);
  printf("unescape == original? %s\n",
         memcmp(raw, a, outlen) ? "no" : "YES");
  if(raw)
    curl_free(raw);

  /* deprecated API */
  raw = curl_unescape(ptr, (int)strlen(ptr));
  if(!raw) {
    res = TEST_ERR_MAJOR_BAD;
    goto test_cleanup;
  }
  outlen = (int)strlen(raw);
  printf("[old] outlen == %d\n", outlen);
  printf("[old] unescape == original? %s\n",
         memcmp(raw, a, outlen) ? "no" : "YES");
  if(raw)
    curl_free(raw);
  if(ptr)
    curl_free(ptr);

  /* weird input length */
  ptr = curl_easy_escape(NULL, (char *)a, -1);
  printf("escape -1 length: %s\n", ptr);

  /* weird input length */
  outlen = 2017; /* just a value */
  ptr = curl_easy_unescape(NULL, (char *)"moahahaha", -1, &outlen);
  printf("unescape -1 length: %s %d\n", ptr, outlen);

test_cleanup:
  if(ptr)
    curl_free(ptr);
  curl_global_cleanup();

  return (int)res;
}
示例#23
0
/* for ABI-compatibility with previous versions */
char *curl_unescape(const char *string, int length)
{
  return curl_easy_unescape(NULL, string, length, NULL);
}
示例#24
0
文件: file.c 项目: jgsogo/curl
/*
 * file_connect() gets called from Curl_protocol_connect() to allow us to
 * do protocol-specific actions at connect-time.  We emulate a
 * connect-then-transfer protocol and "connect" to the file here
 */
static CURLcode file_connect(struct connectdata *conn, bool *done)
{
  struct SessionHandle *data = conn->data;
  char *real_path;
  struct FILEPROTO *file = data->req.protop;
  int fd;
#ifdef DOS_FILESYSTEM
  int i;
  char *actual_path;
#endif
  int real_path_len;

  real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len);
  if(!real_path)
    return CURLE_OUT_OF_MEMORY;

#ifdef DOS_FILESYSTEM
  /* If the first character is a slash, and there's
     something that looks like a drive at the beginning of
     the path, skip the slash.  If we remove the initial
     slash in all cases, paths without drive letters end up
     relative to the current directory which isn't how
     browsers work.

     Some browsers accept | instead of : as the drive letter
     separator, so we do too.

     On other platforms, we need the slash to indicate an
     absolute pathname.  On Windows, absolute paths start
     with a drive letter.
  */
  actual_path = real_path;
  if((actual_path[0] == '/') &&
      actual_path[1] &&
     (actual_path[2] == ':' || actual_path[2] == '|')) {
    actual_path[2] = ':';
    actual_path++;
    real_path_len--;
  }

  /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
  for(i=0; i < real_path_len; ++i)
    if(actual_path[i] == '/')
      actual_path[i] = '\\';
    else if(!actual_path[i]) /* binary zero */
      return CURLE_URL_MALFORMAT;

  fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
  file->path = actual_path;
#else
  if(memchr(real_path, 0, real_path_len))
    /* binary zeroes indicate foul play */
    return CURLE_URL_MALFORMAT;

  fd = open_readonly(real_path, O_RDONLY);
  file->path = real_path;
#endif
  file->freepath = real_path; /* free this when done */

  file->fd = fd;
  if(!data->set.upload && (fd == -1)) {
    failf(data, "Couldn't open file %s", data->state.path);
    file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
    return CURLE_FILE_COULDNT_READ_FILE;
  }
  *done = TRUE;

  return CURLE_OK;
}
示例#25
0
int getlink(char *link, CURL *curl, int ntry)
{
    FILE *pagefile;
    char *pagefilename;
    char *filename_clean;
    int ret;
    long dlenght = 0;
    curl_off_t existsize = 0;
    struct stat statbuf;
    struct myprogress prog; 
    
    interv_count = 0;

    pagefilename = basename(link);
    filename_clean = curl_easy_unescape(curl, pagefilename, 0, 0);
    pagefile = fopen("/dev/null", "w");

    if(ntry == 0)
        fprintf(stdout, "  => Getting '%s':\n", filename_clean);


    curl_easy_setopt(curl, CURLOPT_URL, link);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
    curl_easy_setopt(curl, CURLOPT_RANGE, "0-1");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, pagefile);

    
    ret = curl_easy_perform(curl);
//         printf("CURL: %d\n", ret);
    fclose(pagefile);
    
    if(manage_ret(curl, ret) == 1)
        return 0;
    
    curl_easy_reset(curl);
//     prog->filename = pagefilename_clean;
    
    if((stat(pagefilename, &statbuf) == 0))
    {
        existsize = statbuf.st_size;
        float kbsize = statbuf.st_size / 1024;
        float mbsize = kbsize / 1024;
        float gbsize = mbsize / 1024;
    
        pagefile = fopen(filename_clean, "a+");
        if(ntry == 0)
        {
            printf(" (Already downloaded: ");
            if(statbuf.st_size < 1024)
                printf("%5.1f B)\n", (float)statbuf.st_size);
            if((kbsize < 1024) && (statbuf.st_size > 1024))
                printf("%5.1f kB)\n", kbsize);
            if((kbsize > 1024) && (mbsize < 1024))
                printf("%5.1f mB)\n", mbsize);
            if(mbsize > 1024)
                printf("%5.1f GB)\n", gbsize);
        }
        
    }

    if(existsize > 0)
    {
        curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE , existsize);
    }
    else
    {
//         curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE , 0);
        pagefile = fopen(filename_clean, "wb");
    }
    
    curl_free(filename_clean);
    prog.startime = time(NULL);
    
    curl_easy_setopt(curl, CURLOPT_URL, link);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress);
    curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, pagefile);
    
    curl_easy_setopt(curl, CURLOPT_RANGE, NULL);
    ret = curl_easy_perform(curl);
    curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_UPLOAD, &dlenght);

    if((existsize > 0) && (dlenght == 0) && (ret == 33))
    {
        fprintf(stdout, "\n (file already complete)\n");
        fclose(pagefile);
        return 0;
    }

    if(ret != 0)
    {
        if(ntry == NTRYMAX)
        {
            perror("Download failed");
        }
        fclose(pagefile);
        return -1;
    }
    
    
    fclose(pagefile);
    fprintf(stdout, "\n");
    return 0;
}
static int burrow_backend_http_json_callback(void *ctx,
					     int type,
					     const JSON_value* value)
{
  json_processing_t* jproc = (json_processing_t *)ctx;

  // determine what command is being processed.
  burrow_command_t bcommand = burrow_backend_http_get_command(jproc->backend);

  /* This section is for commands that return burrow messages, whether they
     return one message or a list of messages.
  */
  if (
      (bcommand == BURROW_CMD_GET_MESSAGE) ||
      (bcommand == BURROW_CMD_GET_MESSAGES) ||
      (bcommand == BURROW_CMD_UPDATE_MESSAGE) ||
      (bcommand == BURROW_CMD_UPDATE_MESSAGES) ||
      (bcommand == BURROW_CMD_DELETE_MESSAGE) ||
      (bcommand == BURROW_CMD_DELETE_MESSAGES))
    {
      switch(type) {
      case JSON_T_ARRAY_BEGIN:
      case JSON_T_ARRAY_END:
	break;
      case JSON_T_OBJECT_BEGIN:
	// make sure we have attributes, and they are unset
	jproc->attributes = burrow_attributes_create(jproc->attributes, 0);
	break;
      case JSON_T_OBJECT_END:
	/*
	 * we got the end of an object.  We take this to mean we have
	 * a complete message at this point, which we should pass off
	 * to the appropriate callback.
	 */
	burrow_callback_message(burrow_backend_http_get_burrow(jproc->backend),
				jproc->message_id,
				(uint8_t *)jproc->body,
				jproc->body_size,
				jproc->attributes);
	/* clean up for the next message, in case there is one */
	if (jproc->message_id) {
	  free(jproc->message_id);
	  jproc->message_id = 0;
	}
	if (jproc->body) {
	  free(jproc->body);
	  jproc->body = 0;
	}
	jproc->body_size = 0;
	/* Make sure we have a clean set of attributes */
	if (jproc->attributes) {
	  burrow_attributes_unset_all(jproc->attributes);
	} else {
	  jproc->attributes = burrow_attributes_create(0,0);
	}

	break;
      case JSON_T_KEY:
	// We don't check if the key is valid until later,
	// when we have the value
	jproc->is_key = 1;
	if (jproc->key)
	  free(jproc->key);

	jproc->key = malloc(value->vu.str.length + 1);
	if (jproc->key == NULL) {
	  burrow_error(burrow_backend_http_get_burrow(jproc->backend),
		       ENOMEM,
		       "ERROR!  malloc failed during JSON parsing");
	  return 0;
	}
	memcpy(jproc->key, value->vu.str.value, value->vu.str.length + 1);
	break;
      case JSON_T_STRING:
	// Now check if key is valid
	if(jproc->is_key) {
	  jproc->is_key = 0;
	  if (strcmp(jproc->key, "id") == 0) {
	    char *message_id =
	      curl_easy_unescape(burrow_backend_http_get_curl_easy_handle(jproc->backend),
				 value->vu.str.value,
				 0, 0);
	    if (jproc->message_id)
	      free(jproc->message_id);
	    size_t len = strlen(message_id);
	    jproc->message_id = malloc(len + 1);
	    if(jproc->message_id == NULL) {
	      burrow_error(burrow_backend_http_get_burrow(jproc->backend),
			   ENOMEM,
			   "ERROR!  malloc failed!\n");
	      return 0;
	    }
	    memcpy(jproc->message_id, message_id, len + 1);
	    curl_free(message_id);
	  } else if (strcmp(jproc->key, "body") == 0) {
	    jproc->body_size = value->vu.str.length;
	    jproc->body = malloc(jproc->body_size);
	    if (jproc->body == 0) {
	      burrow_error(burrow_backend_http_get_burrow(jproc->backend),
			   ENOMEM,
			   "ERROR!  malloc failed!\n");
	      return 0;
	    }
	    memcpy(jproc->body, value->vu.str.value, jproc->body_size + 1);
	  } else {
	    burrow_error(burrow_backend_http_get_burrow(jproc->backend),
			 EINVAL,
			 "ERROR!  unrecognized string valued key \"%s\"=\"%s\"\n", jproc->key, value->vu.str.value);
	    return 0;
	  }
	} else {
	  // We never got a key?
	  // is this even possible without the json parser yakking?
	  return 0;
	}
	break;
      case JSON_T_INTEGER:
	if(jproc->is_key) {
	  jproc->is_key = 0;
	  if (strcmp(jproc->key, "hide") == 0) {
	    burrow_attributes_set_hide(jproc->attributes,
				       (uint32_t)value->vu.integer_value);
	  } else if (strcmp(jproc->key, "ttl") == 0) {
	    burrow_attributes_set_ttl(jproc->attributes,
				      (uint32_t)value->vu.integer_value);
	  } else {
	     burrow_error(burrow_backend_http_get_burrow(jproc->backend),
			  EINVAL,
			  "WARNING! JSON parsing found unrecognized integer key \"%s\"=%d\n",
			  jproc->key, value->vu.integer_value);
	    return 0;
	  }
	}
	break;
      default:
	burrow_error(burrow_backend_http_get_burrow(jproc->backend),
		     EINVAL,
		     "WARNING! JSON parsing found unexpected type = %d\n",
		     type);
	return 0;
	break;
      }
    } else if ((bcommand == BURROW_CMD_GET_QUEUES) ||
	       (bcommand == BURROW_CMD_GET_ACCOUNTS))
    {
      /* This section is for commands that return lists of strings, such as when
       * you list the queues or the accounts
       */
      switch(type) {
      case JSON_T_ARRAY_BEGIN:
	break;
      case JSON_T_ARRAY_END:
	/* Does not seem to be anything to do here. */
	break;
      case JSON_T_STRING:
	if (bcommand == BURROW_CMD_GET_ACCOUNTS) {
	  char *account = curl_easy_unescape(burrow_backend_http_get_curl_easy_handle(jproc->backend),
					     value->vu.str.value, 0,0);
	  burrow_callback_account(burrow_backend_http_get_burrow(jproc->backend),
				  account);
	  curl_free(account);
	} else if (bcommand == BURROW_CMD_GET_QUEUES) {
	  char *queue = curl_easy_unescape(burrow_backend_http_get_curl_easy_handle(jproc->backend),
					   value->vu.str.value, 0,0);
	  burrow_callback_queue(burrow_backend_http_get_burrow(jproc->backend),
				queue);
	  curl_free(queue);
	}
	break;
      default:
	burrow_error(burrow_backend_http_get_burrow(jproc->backend),
		     EINVAL,
		     "WARNING! JSON parsing found unexpected type = %d\n",
		     type);

	return 0;
	break;
      }
    }

  return 1;
}
示例#27
0
static CURLcode gopher_do(struct connectdata *conn, bool *done)
{
  CURLcode result=CURLE_OK;
  struct SessionHandle *data=conn->data;
  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];

  curl_off_t *bytecount = &data->req.bytecount;
  char *path = data->state.path;
  char *sel;
  char *sel_org = NULL;
  ssize_t amount, k;
  int len;

  *done = TRUE; /* unconditionally */

  /* Create selector. Degenerate cases: / and /1 => convert to "" */
  if(strlen(path) <= 2) {
    sel = (char *)"";
    len = (int)strlen(sel);
  }
  else {
    char *newp;
    size_t j, i;

    /* Otherwise, drop / and the first character (i.e., item type) ... */
    newp = path;
    newp+=2;

    /* ... then turn ? into TAB for search servers, Veronica, etc. ... */
    j = strlen(newp);
    for(i=0; i<j; i++)
      if(newp[i] == '?')
        newp[i] = '\x09';

    /* ... and finally unescape */
    sel = curl_easy_unescape(data, newp, 0, &len);
    if(!sel)
      return CURLE_OUT_OF_MEMORY;
    sel_org = sel;
  }

  /* We use Curl_write instead of Curl_sendf to make sure the entire buffer is
     sent, which could be sizeable with long selectors. */
  k = curlx_uztosz(len);

  for(;;) {
    result = Curl_write(conn, sockfd, sel, k, &amount);
    if(!result) { /* Which may not have written it all! */
      result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
      if(result) {
        free(sel_org);
        return result;
      }
      k -= amount;
      sel += amount;
      if(k < 1)
        break; /* but it did write it all */
    }
    else {
      failf(data, "Failed sending Gopher request");
      free(sel_org);
      return result;
    }
    /* Don't busyloop. The entire loop thing is a work-around as it causes a
       BLOCKING behavior which is a NO-NO. This function should rather be
       split up in a do and a doing piece where the pieces that aren't
       possible to send now will be sent in the doing function repeatedly
       until the entire request is sent.

       Wait a while for the socket to be writable. Note that this doesn't
       acknowledge the timeout.
    */
    Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 100);
  }

  free(sel_org);

  /* We can use Curl_sendf to send the terminal \r\n relatively safely and
     save allocing another string/doing another _write loop. */
  result = Curl_sendf(sockfd, conn, "\r\n");
  if(result) {
    failf(data, "Failed sending Gopher request");
    return result;
  }
  result = Curl_client_write(conn, CLIENTWRITE_HEADER, (char *)"\r\n", 2);
  if(result)
    return result;

  Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
                      -1, NULL); /* no upload */
  return CURLE_OK;
}
示例#28
0
int
doit(int sockfd, uint16_t num_trackers, in_addr_t *trackers, uint16_t maxpeers,
	uint16_t num_pkg_servers, in_addr_t *pkg_servers, CURL *curlhandle)
{
	struct timeval		start_time;
#ifdef	TIMEIT
#endif
	struct timeval		end_time;
	unsigned long long	s, e;
	char			*forminfo;
	char			*range;
	char			filename[PATH_MAX];

	gettimeofday(&start_time, NULL);

	bzero(filename, sizeof(filename));

	if ((forminfo = getenv("QUERY_STRING")) == NULL) {
		senderror(500, "No QUERY_STRING", errno);
		return(0);
	}

	if ((range = getenv("HTTP_RANGE")) != NULL) {
		char	*ptr;

		if ((ptr = strchr(range, '=')) != NULL) {
			range = ptr + 1;
		}
	}

	if (getargs(forminfo, filename) != 0) {
		senderror(500, "getargs():failed", errno);
		return(0);
	}

	
	//let's unescape filename
        char * filename_unescaped;
	filename_unescaped = curl_easy_unescape(curlhandle, filename , 0, NULL );
	//filename_unescaped will be equal or shorter to filename
	strcpy(filename, filename_unescaped);
	curl_free(filename_unescaped);

	/*
	 * the time is 'epoch' time
	 */
	logmsg("%d : doit:file %s\n", start_time.tv_sec, basename(filename));
#ifdef	DEBUG
	logmsg("doit:getting file (%s)\n", filename);
#endif

	/*
	 * if the file is local, just read it off the disk, otherwise, ask
	 * the tracker where the file is
	 */
	if (getlocal(filename, range) != 0) {
		if (trackfile(sockfd, filename, range, num_trackers, trackers,
				maxpeers, num_pkg_servers, pkg_servers,
				curlhandle) != 0) {
			senderror(404, "File not found", 0);
		}
	}

#ifdef	DEBUG
	logmsg("doit:done:file (%s)\n\n", filename);
#endif

#ifdef	TIMEIT
#endif
	gettimeofday(&end_time, NULL);
	s = (start_time.tv_sec * 1000000) + start_time.tv_usec;
	e = (end_time.tv_sec * 1000000) + end_time.tv_usec;
	logmsg("doit:svc time: %lld usec file %s from %s\n\n",
		(e - s) - curltime, basename(filename), fromip);

	return(0);
}
示例#29
0
ZipInfo* PartialZipInit(const char* url)
{
	ZipInfo* info = (ZipInfo*) malloc(sizeof(ZipInfo));
	info->url = strdup(url);
	info->centralDirectoryRecvd = 0;
	info->centralDirectoryEndRecvd = 0;
	info->centralDirectoryDesc = NULL;

	info->hCurl = curl_easy_init();

	curl_easy_setopt(info->hCurl, CURLOPT_URL, info->url);
	curl_easy_setopt(info->hCurl, CURLOPT_FOLLOWLOCATION, 1);
	curl_easy_setopt(info->hCurl, CURLOPT_NOBODY, 1);
	curl_easy_setopt(info->hCurl, CURLOPT_WRITEFUNCTION, dummyReceive);
	curl_easy_setopt(info->hCurl, CURLOPT_SSL_VERIFYPEER, 0);

	if(strncmp(info->url, "file://", 7) == 0)
	{
		char path[1024];
		strcpy(path, info->url + 7);
		char* filePath = (char*) curl_easy_unescape(info->hCurl, path, 0,  NULL);
		FILE* f = fopen(filePath, "rb");
		if(!f)
		{
			curl_free(filePath);
			curl_easy_cleanup(info->hCurl);
			free(info->url);
			free(info);

			return NULL;
		}

		fseek(f, 0, SEEK_END);
		info->length = ftell(f);
		fclose(f);

		curl_free(filePath);
	}
	else
	{
		curl_easy_perform(info->hCurl);

		double dFileLength;
		curl_easy_getinfo(info->hCurl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &dFileLength);
		info->length = dFileLength;
	}

	char sRange[100];
	uint64_t start;

	if(info->length > (0xffff + sizeof(EndOfCD)))
		start = info->length - 0xffff - sizeof(EndOfCD);
	else
		start = 0;

	uint64_t end = info->length - 1;

	sprintf(sRange, "%" PRIu64 "-%" PRIu64, start, end);

	curl_easy_setopt(info->hCurl, CURLOPT_WRITEFUNCTION, receiveCentralDirectoryEnd);
	curl_easy_setopt(info->hCurl, CURLOPT_WRITEDATA, info);
	curl_easy_setopt(info->hCurl, CURLOPT_RANGE, sRange);
	curl_easy_setopt(info->hCurl, CURLOPT_HTTPGET, 1);

	curl_easy_perform(info->hCurl);

	char* cur;
	for(cur = info->centralDirectoryEnd; cur < (info->centralDirectoryEnd + (end - start - 1)); cur++)
	{
		EndOfCD* candidate = (EndOfCD*) cur;
		uint32_t signature = candidate->signature;
		FLIPENDIANLE(signature);
		if(signature == 0x06054b50)
		{
			uint16_t lenComment = candidate->lenComment;
			FLIPENDIANLE(lenComment);
			if((cur + lenComment + sizeof(EndOfCD)) == (info->centralDirectoryEnd + info->centralDirectoryEndRecvd))
			{
				FLIPENDIANLE(candidate->diskNo);
				FLIPENDIANLE(candidate->CDDiskNo);
				FLIPENDIANLE(candidate->CDDiskEntries);
				FLIPENDIANLE(candidate->CDEntries);
				FLIPENDIANLE(candidate->CDSize);
				FLIPENDIANLE(candidate->CDOffset);
				FLIPENDIANLE(candidate->lenComment);
				info->centralDirectoryDesc = candidate;
				break;
			}
		}

	}

	if(info->centralDirectoryDesc)
	{
		info->centralDirectory = malloc(info->centralDirectoryDesc->CDSize);
		start = info->centralDirectoryDesc->CDOffset;
		end = start + info->centralDirectoryDesc->CDSize - 1;
		sprintf(sRange, "%" PRIu64 "-%" PRIu64, start, end);
		curl_easy_setopt(info->hCurl, CURLOPT_WRITEFUNCTION, receiveCentralDirectory);
		curl_easy_setopt(info->hCurl, CURLOPT_WRITEDATA, info);
		curl_easy_setopt(info->hCurl, CURLOPT_RANGE, sRange);
		curl_easy_setopt(info->hCurl, CURLOPT_HTTPGET, 1);
		curl_easy_perform(info->hCurl);

		flipFiles(info);

		return info;
	}
	else 
	{
		curl_easy_cleanup(info->hCurl);
		free(info->url);
		free(info);
		return NULL;
	}
}
示例#30
0
std::vector<gameFile> galaxyAPI::fileJsonNodeToGameFileVector(const std::string& gamename, const Json::Value& json, const unsigned int& type, const unsigned int& platform, const unsigned int& lang, const bool& useDuplicateHandler)
{
    std::vector<gameFile> gamefiles;
    unsigned int iInfoNodes = json.size();
    for (unsigned int i = 0; i < iInfoNodes; ++i)
    {
        Json::Value infoNode = json[i];
        unsigned int iFiles = infoNode["files"].size();
        std::string name = infoNode["name"].asString();

        unsigned int iPlatform = GlobalConstants::PLATFORM_WINDOWS;
        unsigned int iLanguage = GlobalConstants::LANGUAGE_EN;
        if (!(type & GFTYPE_EXTRA))
        {
            iPlatform = Util::getOptionValue(infoNode["os"].asString(), GlobalConstants::PLATFORMS);
            iLanguage = Util::getOptionValue(infoNode["language"].asString(), GlobalConstants::LANGUAGES);

            if (!(iPlatform & platform))
                continue;

            if (!(iLanguage & lang))
                continue;
        }

        for (unsigned int j = 0; j < iFiles; ++j)
        {
            Json::Value fileNode = infoNode["files"][j];
            std::string downlink = fileNode["downlink"].asString();

            Json::Value downlinkJson = this->getResponseJson(downlink);
            if (downlinkJson.empty())
                continue;

            std::string downlink_url = downlinkJson["downlink"].asString();
            std::string downlink_url_unescaped = (std::string)curl_easy_unescape(curlhandle, downlink_url.c_str(), downlink_url.size(), NULL);
            std::string path;

            // GOG has changed the url formatting few times between 2 different formats.
            // Try to get proper file name in both cases.
            size_t filename_end_pos;
            if (downlink_url_unescaped.find("?path=") != std::string::npos)
                filename_end_pos = downlink_url_unescaped.find_first_of("&");
            else
                filename_end_pos = downlink_url_unescaped.find_first_of("?");

            if (downlink_url_unescaped.find("/" + gamename + "/") != std::string::npos)
            {
                path.assign(downlink_url_unescaped.begin()+downlink_url_unescaped.find("/" + gamename + "/"), downlink_url_unescaped.begin()+filename_end_pos);
            }
            else
            {
                path.assign(downlink_url_unescaped.begin()+downlink_url_unescaped.find_last_of("/")+1, downlink_url_unescaped.begin()+filename_end_pos);
                path = "/" + gamename + "/" + path;
            }

            // Workaround for filename issue caused by different (currently unknown) url formatting scheme
            // https://github.com/Sude-/lgogdownloader/issues/126
            if (path.find("?") != std::string::npos)
            {
                if (path.find_last_of("?") > path.find_last_of("/"))
                {
                    path.assign(path.begin(), path.begin()+path.find_last_of("?"));
                }
            }

            gameFile gf;
            gf.gamename = gamename;
            gf.type = type;
            gf.id = fileNode["id"].asString();
            gf.name = name;
            gf.path = path;
            gf.size = Util::getJsonUIntValueAsString(fileNode["size"]);
            gf.updated = 0; // assume not updated
            gf.galaxy_downlink_json_url = downlink;

            if (!(type & GFTYPE_EXTRA))
            {
                gf.platform = iPlatform;
                gf.language = iLanguage;

                if (useDuplicateHandler)
                {
                    bool bDuplicate = false;
                    for (unsigned int k = 0; k < gamefiles.size(); ++k)
                    {
                        if (gamefiles[k].path == gf.path)
                        {
                            gamefiles[k].language |= gf.language; // Add language code to installer
                            bDuplicate = true;
                            break;
                        }
                    }
                    if (bDuplicate)
                        continue;
                }
            }

            gamefiles.push_back(gf);
        }
    }

    return gamefiles;
}