Beispiel #1
0
/*
	Given a URL, it returns a parsed_url, any fields of which may be null
	if they are not present or parsable in the URL.
*/
parsed_url url_parse(char *url)
{
	substr scheme, user, passwd, host, port, path;
	parsed_url r;
	char *cursor;

	scheme = user = passwd = host = port = path = (substr) { 0, 0 };

	cursor = url_scheme(url, &scheme);
	cursor = url_user_pass(cursor, &user, &passwd);
	cursor = url_host(cursor, &host);
	cursor = url_port(cursor, &port);
	url_path(cursor, &path);

	cut_piece(r.scheme, scheme);
	cut_piece(r.user, user);
	cut_piece(r.passwd, passwd);
	cut_piece(r.host, host);
	cut_piece(r.path, path);

	if(port.start != NULL)
		r.port = atoi(port.start);
	else
		r.port = 0;

	return r;
}
Beispiel #2
0
url
resolve_in_path (url u) {
  if (use_which) {
    string name = escape_sh (as_string (u));
    string which= var_eval_system ("which " * name * " 2> /dev/null");
    if (ends (which, name))
      return which;
    else if ((which != "") &&
	     (!starts (which, "which: ")) &&
	     (!starts (which, "no ")))
      cout << "TeXmacs] " << which << "\n";
  }
  return resolve (url_path ("$PATH") * u, "x");
}
Beispiel #3
0
url
url_general (string name, int type= URL_SYSTEM) {
  if (starts (name, "local:")) return url_local (name (6, N (name)));
  if (starts (name, "file://")) return url_file (name (7, N (name)));
  if (starts (name, "http://")) return url_http (name (7, N (name)));
  if (starts (name, "https://")) return url_https (name (8, N (name)));
  if (starts (name, "ftp://")) return url_ftp (name (6, N (name)));
  if (starts (name, "tmfs://")) return url_tmfs (name (7, N (name)));
  if (starts (name, "//")) return url_blank (name (2, N (name)));
  if (heuristic_is_path (name, type)) return url_path (name, type);
  if (heuristic_is_default (name, type)) return url_default (name, type);
  if (heuristic_is_mingw_default (name, type)) return url_mingw_default (name, type);
  if (heuristic_is_http (name)) return url_http (name);
  if (heuristic_is_ftp (name)) return url_ftp (name);
  return url_get_name (name, type);
}
Beispiel #4
0
char *url_to_path(const char *url)
{
	char *path;
	char *respath;
	url_func_result res; /* result from url routines */

	res = url_path(url, &path);
	if (res != URL_FUNC_OK) {
		return NULL;
	}

	res = url_unescape(path, &respath);
	free(path);
	if (res != URL_FUNC_OK) {
		return NULL;
	}

	return respath;
}
Beispiel #5
0
struct gui_download_window *gui_download_window_create(download_context *ctx,
		struct gui_window *gui)
{
	const char *url = download_context_get_url(ctx);
	const char *mime_type = download_context_get_mime_type(ctx);
	const char *temp_name;
	char *scheme = NULL;
	char *filename = NULL;
	struct gui_download_window *dw;
	bool space_warning = false;
	os_error *error;
	url_func_result res;
	char *local_path;
	utf8_convert_ret err;
	size_t i, last_dot;

	dw = malloc(sizeof *dw);
	if (!dw) {
		warn_user("NoMemory", 0);
		return 0;
	}

	dw->ctx = ctx;
	dw->saved = false;
	dw->close_confirmed = false;
	dw->error = false;
	dw->query = QUERY_INVALID;
	dw->received = 0;
	dw->total_size = download_context_get_total_length(ctx);
	strncpy(dw->url, url, sizeof dw->url);
	dw->url[sizeof dw->url - 1] = 0;
	dw->status[0] = 0;
	gettimeofday(&dw->start_time, 0);
	dw->last_time = dw->start_time;
	dw->last_received = 0;
	dw->file_type = 0;
	dw->average_rate = 0;
	dw->average_points = 0;

	/* Get scheme from URL */
	res = url_scheme(url, &scheme);
	if (res == URL_FUNC_NOMEM) {
		warn_user("NoMemory", 0);
		free(dw);
		return 0;
	} else if (res == URL_FUNC_OK) {
		/* If we have a scheme and it's "file", then
		 * attempt to use the local filetype directly */
		if (strcasecmp(scheme, "file") == 0) {
			char *path = NULL;
			res = url_path(url, &path);
			if (res == URL_FUNC_NOMEM) {
				warn_user("NoMemory", 0);
				free(scheme);
				free(dw);
				return 0;
			} else if (res == URL_FUNC_OK) {
				char *raw_path = curl_unescape(path,
						strlen(path));
				if (raw_path == NULL) {
					warn_user("NoMemory", 0);
					free(path);
					free(scheme);
					free(dw);
					return 0;
				}
				dw->file_type =
					ro_filetype_from_unix_path(raw_path);
				curl_free(raw_path);
				free(path);
			}
		}

		free(scheme);
	}

	/* If we still don't have a filetype (i.e. failed reading local
	 * one or fetching a remote object), then use the MIME type */
	if (dw->file_type == 0) {
		/* convert MIME type to RISC OS file type */
		error = xmimemaptranslate_mime_type_to_filetype(mime_type,
				&(dw->file_type));
		if (error) {
			LOG(("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s",
					error->errnum, error->errmess));
			warn_user("MiscError", error->errmess);
			dw->file_type = 0xffd;
		}
	}

	/* open temporary output file */
	temp_name = ro_gui_download_temp_name(dw);
	if (!ro_gui_download_check_space(dw, temp_name, NULL)) {
		/* issue a warning but continue with the download because the
		   user can save it to another medium whilst it's downloading */
		space_warning = true;
	}
	error = xosfind_openoutw(osfind_NO_PATH | osfind_ERROR_IF_DIR,
			temp_name, 0, &dw->file);
	if (error) {
		LOG(("xosfind_openoutw: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("SaveError", error->errmess);
		free(dw);
		return 0;
	}

	/* fill in download window icons */
	download_template->icons[ICON_DOWNLOAD_URL].data.indirected_text.text =
			dw->url;
	download_template->icons[ICON_DOWNLOAD_URL].data.indirected_text.size =
			sizeof dw->url;

	download_template->icons[ICON_DOWNLOAD_STATUS].data.indirected_text.
			text = dw->status;
	download_template->icons[ICON_DOWNLOAD_STATUS].data.indirected_text.
			size = sizeof dw->status;

	sprintf(dw->sprite_name, "file_%.3x", dw->file_type);
	if (!ro_gui_wimp_sprite_exists(dw->sprite_name))
		strcpy(dw->sprite_name, "file_xxx");
	download_template->icons[ICON_DOWNLOAD_ICON].data.indirected_sprite.id =
			(osspriteop_id) dw->sprite_name;

	/* Get a suitable path- and leafname for the download. */
	temp_name = download_context_get_filename(dw->ctx);

	if (temp_name == NULL)
		temp_name = messages_get("SaveObject");

	if (temp_name != NULL)
		filename = strdup(temp_name);

	if (filename == NULL) {
		LOG(("Failed to establish download filename."));
		warn_user("SaveError", error->errmess);
		free(dw);
		return 0;
	}

	for (i = 0, last_dot = (size_t) -1; filename[i] != '\0'; i++) {
		const char c = filename[i];

		if (c == '.') {
			last_dot = i;
			filename[i] = '/';
		} else if (c <= ' ' || strchr(":*#$&@^%\\", c) != NULL)
			filename[i] = '_';
	}

	if (option_strip_extensions && last_dot != (size_t) -1)
		filename[last_dot] = '\0';

	if (download_dir != NULL && strlen(download_dir) > 0)
		snprintf(dw->path, RO_DOWNLOAD_MAX_PATH_LEN, "%s.%s",
				download_dir, filename);
	else
		snprintf(dw->path, RO_DOWNLOAD_MAX_PATH_LEN, "%s",
				filename);

	err = utf8_to_local_encoding(dw->path, 0, &local_path);
	if (err != UTF8_CONVERT_OK) {
		/* badenc should never happen */
		assert(err != UTF8_CONVERT_BADENC);
		LOG(("utf8_to_local_encoding failed"));
		warn_user("NoMemory", 0);
		free(dw);
		return 0;
	}
	else {
		strncpy(dw->path, local_path, sizeof dw->path);
		free(local_path);
	}

	download_template->icons[ICON_DOWNLOAD_PATH].data.indirected_text.text =
			dw->path;
	download_template->icons[ICON_DOWNLOAD_PATH].data.indirected_text.size =
			sizeof dw->path;

	download_template->icons[ICON_DOWNLOAD_DESTINATION].data.
			indirected_text.text = dw->path;
	download_template->icons[ICON_DOWNLOAD_DESTINATION].data.
			indirected_text.size = sizeof dw->path;

	download_template->icons[ICON_DOWNLOAD_DESTINATION].flags |=
			wimp_ICON_DELETED;

	/* create and open the download window */
	error = xwimp_create_window(download_template, &dw->window);
	if (error) {
		LOG(("xwimp_create_window: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
		free(dw);
		return 0;
	}

	dw->prev = 0;
	dw->next = download_window_list;
	if (download_window_list)
		download_window_list->prev = dw;
	download_window_list = dw;

	ro_gui_download_update_status(dw);

	ro_gui_dialog_open(dw->window);

	ro_gui_wimp_event_set_user_data(dw->window, dw);
	ro_gui_wimp_event_register_mouse_click(dw->window, ro_gui_download_click);
	ro_gui_wimp_event_register_keypress(dw->window, ro_gui_download_keypress);
	ro_gui_wimp_event_register_close_window(dw->window, ro_gui_download_close);

	/* issue the warning now, so that it appears in front of the download
	 * window! */
	if (space_warning)
		warn_user("DownloadWarn", messages_get("NoDiscSpace"));

	return dw;
}
Beispiel #6
0
bool
is_secure (url u) {
  return descends (u, expand (url_path ("$TEXMACS_SECURE_PATH")));
}
Beispiel #7
0
    void link_check::do_url( const string & url, const string & library_name,
      const path & source_path, bool no_link_errors, bool allow_external_content,
        std::string::const_iterator contents_begin, std::string::const_iterator url_start )
        // precondition: source_path.is_complete()
    {
      if(!no_link_errors && url.empty()) {
        ++m_invalid_errors;
        int ln = std::count( contents_begin, url_start, '\n' ) + 1;
        error( library_name, source_path, "Empty URL.", ln );
        return;
      }

      // Decode ampersand encoded characters.
      string decoded_url = is_css(source_path) ? url : decode_ampersands(url);
      if(decoded_url.empty()) {
        if(!no_link_errors) {
          ++m_invalid_errors;
          int ln = std::count( contents_begin, url_start, '\n' ) + 1;
          error( library_name, source_path,
            "Invalid URL (invalid ampersand encodings): " + url, ln );
        }
        return;
      }
    
      boost::smatch m;
      if(!boost::regex_match(decoded_url, m, url_decompose_regex)) {
        if(!no_link_errors) {
          ++m_invalid_errors;
          int ln = std::count( contents_begin, url_start, '\n' ) + 1;
          error( library_name, source_path, "Invalid URL: " + decoded_url, ln );
        }
        return;
      }

      bool scheme_matched = m[2].matched,
        authority_matched = m[4].matched,
        //query_matched = m[7].matched,
        fragment_matched = m[9].matched;

      std::string scheme(m[2]),
        authority(m[4]),
        url_path(m[5]),
        //query(m[7]),
        fragment(m[9]);

      // Check for external content
      if(!allow_external_content && (authority_matched || scheme_matched)) {
        if(!no_link_errors) {
          ++m_invalid_errors;
          int ln = std::count( contents_begin, url_start, '\n' ) + 1;
          error( library_name, source_path, "External content: " + decoded_url, ln );
        }
      }

      // Protocol checks
      if(scheme_matched) {
        if(scheme == "http" || scheme == "https") {
          // All http links should have a hostname. Generally if they don't
          // it's by mistake. If they shouldn't, then a protocol isn't
          // required.
          if(!authority_matched) {
            if(!no_link_errors) {
              ++m_invalid_errors;
              int ln = std::count( contents_begin, url_start, '\n' ) + 1;
              error( library_name, source_path, "No hostname: " + decoded_url, ln );
            }
          }

          return;
        }
        else if(scheme == "file") {
          if(!no_link_errors) {
            ++m_invalid_errors;
            int ln = std::count( contents_begin, url_start, '\n' ) + 1;
            error( library_name, source_path,
              "Invalid URL (hardwired file): " + decoded_url, ln );
          }
        }
        else if(scheme == "mailto" || scheme == "ftp" || scheme == "news" || scheme == "javascript") {
          if ( !no_link_errors && is_css(source_path) ) {
            ++m_invalid_errors;
            int ln = std::count( contents_begin, url_start, '\n' ) + 1;
            error( library_name, source_path,
              "Invalid protocol for css: " + decoded_url, ln );
          }
        }
        else {
          if(!no_link_errors) {
            ++m_invalid_errors;
            int ln = std::count( contents_begin, url_start, '\n' ) + 1;
            error( library_name, source_path, "Unknown protocol: '" + scheme + "' in url: " + decoded_url, ln );
          }
        }

        return;
      }

      // Hostname without protocol.
      if(authority_matched) {
        if(!no_link_errors) {
          ++m_invalid_errors;
          int ln = std::count( contents_begin, url_start, '\n' ) + 1;
          error( library_name, source_path,
            "Invalid URL (hostname without protocol): " + decoded_url, ln );
        }
      }

      // Check the fragment identifier
      if ( fragment_matched ) {
        if ( is_css(source_path) ) {
            if ( !no_link_errors ) {
              ++m_invalid_errors;
              int ln = std::count( contents_begin, url_start, '\n' ) + 1;
              error( library_name, source_path,
                "Fragment link in CSS: " + decoded_url, ln );
            }
        }
        else {
          if ( !no_link_errors && fragment.find( '#' ) != string::npos )
          {
            ++m_bookmark_errors;
            int ln = std::count( contents_begin, url_start, '\n' ) + 1;
            error( library_name, source_path, "Invalid bookmark: " + decoded_url, ln );
          }
          else if ( !no_link_errors && url_path.empty() && !fragment.empty()
            // w3.org recommends case-sensitive broken bookmark checking
            // since some browsers do a case-sensitive match.
            && bookmarks.find(decode_percents(fragment)) == bookmarks.end() )
          {
            ++m_broken_errors;
            int ln = std::count( contents_begin, url_start, '\n' ) + 1;
            error( library_name, source_path, "Unknown bookmark: " + decoded_url, ln );
          }
        }

        // No more to do if it's just a fragment identifier
        if(url_path.empty()) return;
      }

      // Detect characters banned by RFC2396:
      if ( !no_link_errors && decoded_url.find_first_of( " <>\"{}|\\^[]'" ) != string::npos )
      {
        ++m_invalid_errors;
        int ln = std::count( contents_begin, url_start, '\n' ) + 1;
        error( library_name, source_path,
          "Invalid character in URL: " + decoded_url, ln );
      }

      // Check that we actually have a path.
      if(url_path.empty()) {
        if(!no_link_errors) {
          ++m_invalid_errors;
          int ln = std::count( contents_begin, url_start, '\n' ) + 1;
          error( library_name, source_path,
            "Invalid URL (empty path in relative url): " + decoded_url, ln );
        }
      }

      // Decode percent encoded characters.
      string decoded_path = decode_percents(url_path);
      if(decoded_path.empty()) {
        if(!no_link_errors) {
          ++m_invalid_errors;
          int ln = std::count( contents_begin, url_start, '\n' ) + 1;
          error( library_name, source_path,
            "Invalid URL (invalid character encodings): " + decoded_url, ln );
        }
        return;
      }

      // strip url of references to current dir
      if ( decoded_path[0]=='.' && decoded_path[1]=='/' ) decoded_path.erase( 0, 2 );

      // url is relative source_path.branch()
      // convert to target_path, which is_complete()
      path target_path;
      try { target_path = source_path.branch_path() /= path( decoded_path ); }
      catch ( const fs::filesystem_error & )
      {
        if(!no_link_errors) {
          int ln = std::count( contents_begin, url_start, '\n' ) + 1;
          ++m_invalid_errors;
          error( library_name, source_path,
            "Invalid URL (error resolving path): " + decoded_url, ln );
        }
        return;
      }

      // create a m_paths entry if necessary
      std::pair< const string, int > entry(
        relative_to( target_path, search_root_path() ), 0 );
      m_path_map::iterator itr( m_paths.find( entry.first ) );
      if ( itr == m_paths.end() )
      {
        if ( fs::exists( target_path ) ) entry.second = m_present;
        itr = m_paths.insert( entry ).first;
      }

      // itr now points to the m_paths entry
      itr->second |= m_linked_to;

      // if target isn't present, the link is broken
      if ( !no_link_errors && (itr->second & m_present) == 0 )
      {
        ++m_broken_errors;
        int ln = std::count( contents_begin, url_start, '\n' ) + 1;
        error( library_name, source_path, "Broken link: " + decoded_url, ln );
      }
    }