예제 #1
0
SCM DLL_PUBLIC
cl_easy_setopt (SCM handle, SCM option, SCM param, SCM big)
{
  handle_post_t *c_handle;
  CURLoption c_option;
  CURLcode code = CURLE_UNSUPPORTED_PROTOCOL;

  SCM_ASSERT (_scm_is_handle (handle), handle, SCM_ARG1, "curl-easy-setopt");
  SCM_ASSERT (scm_is_integer (option), option, SCM_ARG2, "curl-easy-setopt");

  c_handle = _scm_to_handle (handle);
  c_option = (CURLoption) scm_to_int (option);

  if (c_option == CURLOPT_POSTFIELDS)
    {
      if (_scm_can_convert_to_byte_data (param))
        {
          size_t len;
          uint8_t *m = _scm_convert_to_byte_data (param, &len);
          free (c_handle->postfields);
          c_handle->postfields = m;
          curl_easy_setopt (c_handle->handle, CURLOPT_POSTFIELDSIZE, len);
          c_handle->postfieldsize = len;
          code = curl_easy_setopt (c_handle->handle, CURLOPT_POSTFIELDS, (char *) m);
        }
      else
        scm_error (SCM_BOOL_F, "cl-easy-setopt", "CURLOPT_POSTFIELDS requires 8-bit string or bytevector data",
                   SCM_BOOL_F, SCM_BOOL_F);
    }
  else if (c_option == CURLOPT_HTTPHEADER)
    {
      if (_scm_can_convert_to_slist (param))
        {
          /* slists require special handling to free them properly, so
             they are stored with the Curl handle.  */
          struct curl_slist *sl = _scm_convert_to_slist (param);
          if (c_handle->httpheader)
            curl_slist_free_all (c_handle->httpheader);
          c_handle->httpheader = sl;
          code = curl_easy_setopt (c_handle->handle, CURLOPT_HTTPHEADER, sl);
        }
      else
        scm_error (SCM_BOOL_F, "cl-easy-setopt", "CURLOPT_HTTPHEADER requires a list of strings",
                   SCM_BOOL_F, SCM_BOOL_F);
    }
  else if (scm_is_integer (param))
    {
      if (scm_is_true (big))
        code = curl_easy_setopt (c_handle->handle, c_option, scm_to_int64 (param));
      else
        code = curl_easy_setopt (c_handle->handle, c_option, scm_to_long (param));
    }
  else if (scm_is_string (param))
    {
      /* Strings are copied by curl, so they can be freed here. */
      char *str;
      str = scm_to_locale_string (param);
      code = curl_easy_setopt (c_handle->handle, c_option, str);
      free (str);
    }
  else if (_scm_can_convert_to_slist (param))
    {
      /* slists require special handling to free them properly, so
         they are stored with the Curl handle.  */
      struct curl_slist *sl = _scm_convert_to_slist (param);
      int ok = 1;
      if (c_option == CURLOPT_HTTP200ALIASES)
        {
          if (c_handle->http200aliases)
            curl_slist_free_all (c_handle->http200aliases);
          c_handle->http200aliases = sl;
        }
      else if (c_option == CURLOPT_MAIL_RCPT)
        {
          if (c_handle->mail_rcpt)
            curl_slist_free_all (c_handle->mail_rcpt);
          c_handle->mail_rcpt = sl;
        }
      else if (c_option == CURLOPT_QUOTE)
        {
          if (c_handle->quote)
            curl_slist_free_all (c_handle->quote);
          c_handle->quote = sl;
        }
      else if (c_option == CURLOPT_POSTQUOTE)
        {
          if (c_handle->postquote)
            curl_slist_free_all (c_handle->postquote);
          c_handle->postquote = sl;
        }
      else if (c_option == CURLOPT_PREQUOTE)
        {
          if (c_handle->prequote)
            curl_slist_free_all (c_handle->prequote);
          c_handle->prequote = sl;
        }
      else if (c_option == CURLOPT_RESOLVE)
        {
          if (c_handle->resolve)
            curl_slist_free_all (c_handle->resolve);
          c_handle->resolve = sl;
        }
      else if (c_option == CURLOPT_TELNETOPTIONS)
        {
          if (c_handle->telnetoptions)
            curl_slist_free_all (c_handle->telnetoptions);
          c_handle->telnetoptions = sl;
        }
      else
        {
          // Bad slist option
          ok = 0;
        }
      if (ok)
        code = curl_easy_setopt (c_handle->handle, c_option, sl);

    }
  else if (_scm_can_convert_to_httppost (param))
    {
      if (c_option == CURLOPT_HTTPPOST)
        {
          struct curl_httppost *p;
          p = _scm_convert_to_httppost (param);
          free (c_handle->httppost);
          c_handle->httppost = p;
          code = curl_easy_setopt (c_handle, CURLOPT_HTTPPOST, p);
        }
    }
  else if (scm_is_true (scm_input_port_p (param)))
    {
      if (c_option == CURLOPT_READDATA)
        {
          curl_easy_setopt (c_handle->handle, CURLOPT_READFUNCTION, read_callback);
          code = curl_easy_setopt (c_handle->handle, CURLOPT_READDATA, SCM2PTR (param));          
        }
    }
  else
    scm_error (SCM_BOOL_F,
               "curl-easy-setopt",
               "unimplemented option type",
               SCM_BOOL_F,
               SCM_BOOL_F);
  if (code != CURLE_OK)
    scm_error (SCM_BOOL_F,
               "curl-easy-setopt",
               "bad handle",
               SCM_BOOL_F,
               SCM_BOOL_F);

  return SCM_UNSPECIFIED;
}
예제 #2
0
static SCM
gdbscm_arch_disassemble (SCM self, SCM start_scm, SCM rest)
{
  arch_smob *a_smob
    = arscm_get_arch_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct gdbarch *gdbarch = arscm_get_gdbarch (a_smob);
  const SCM keywords[] = {
    port_keyword, offset_keyword, size_keyword, count_keyword, SCM_BOOL_F
  };
  int port_arg_pos = -1, offset_arg_pos = -1;
  int size_arg_pos = -1, count_arg_pos = -1;
  SCM port = SCM_BOOL_F;
  ULONGEST offset = 0;
  unsigned int count = 1;
  unsigned int size;
  ULONGEST start_arg;
  CORE_ADDR start, end;
  CORE_ADDR pc;
  unsigned int i;
  int using_port;
  SCM result;

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, keywords, "U#OUuu",
			      start_scm, &start_arg, rest,
			      &port_arg_pos, &port,
			      &offset_arg_pos, &offset,
			      &size_arg_pos, &size,
			      &count_arg_pos, &count);
  /* START is first stored in a ULONGEST because we don't have a format char
     for CORE_ADDR, and it's not really worth it to have one yet.  */
  start = start_arg;

  if (port_arg_pos > 0)
    {
      SCM_ASSERT_TYPE (gdbscm_is_false (port)
		       || gdbscm_is_true (scm_input_port_p (port)),
		       port, port_arg_pos, FUNC_NAME, _("input port"));
    }
  using_port = gdbscm_is_true (port);

  if (offset_arg_pos > 0
      && (port_arg_pos < 0
	  || gdbscm_is_false (port)))
    {
      gdbscm_out_of_range_error (FUNC_NAME, offset_arg_pos,
				 gdbscm_scm_from_ulongest (offset),
				 _("offset provided but port is missing"));
    }

  if (size_arg_pos > 0)
    {
      if (size == 0)
	return SCM_EOL;
      /* For now be strict about start+size overflowing.  If it becomes
	 a nuisance we can relax things later.  */
      if (start + size < start)
	{
	  gdbscm_out_of_range_error (FUNC_NAME, 0,
				scm_list_2 (gdbscm_scm_from_ulongest (start),
					    gdbscm_scm_from_ulongest (size)),
				     _("start+size overflows"));
	}
      end = start + size - 1;
    }
  else
    end = ~(CORE_ADDR) 0;

  if (count == 0)
    return SCM_EOL;

  result = SCM_EOL;

  for (pc = start, i = 0; pc <= end && i < count; )
    {
      int insn_len = 0;
      struct ui_file *memfile = mem_fileopen ();
      struct cleanup *cleanups = make_cleanup_ui_file_delete (memfile);

      TRY
	{
	  if (using_port)
	    {
	      insn_len = gdbscm_print_insn_from_port (gdbarch, port, offset,
						      pc, memfile, NULL);
	    }
	  else
	    insn_len = gdb_print_insn (gdbarch, pc, memfile, NULL);
	}
      CATCH (except, RETURN_MASK_ALL)
	{
	  GDBSCM_HANDLE_GDB_EXCEPTION_WITH_CLEANUPS (except, cleanups);
	}
      END_CATCH

      std::string as = ui_file_as_string (memfile);

      result = scm_cons (dascm_make_insn (pc, as.c_str (), insn_len),
			 result);

      pc += insn_len;
      i++;
      do_cleanups (cleanups);
    }