sprintf(buf, "CONNECT %s:%i HTTP/1.1\r\nHost: %s:%i\r\n", dest, p->remote_port, dest, p->remote_port);
buf = dupprintf("CONNECT %s:%i HTTP/1.1\r\nHost: %s:%i\r\n", dest, p->remote_port, dest, p->remote_port);
int proxy_http_negotiate (Proxy_Socket p, int change){    if (p->state == PROXY_STATE_NEW) {	/* we are just beginning the proxy negotiate process,	 * so we'll send off the initial bits of the request.	 * for this proxy method, it's just a simple HTTP	 * request	 */	char buf[256], dest[64];	sk_getaddr(p->remote_addr, dest, 64);	sprintf(buf, "CONNECT %s:%i HTTP/1.1\r\nHost: %s:%i\r\n",		dest, p->remote_port, dest, p->remote_port);	sk_write(p->sub_socket, buf, strlen(buf));	if (cfg.proxy_username[0] || cfg.proxy_password[0]) {	    char buf[sizeof(cfg.proxy_username)+sizeof(cfg.proxy_password)];	    char buf2[sizeof(buf)*4/3 + 100];	    int i, j, len;	    sprintf(buf, "%s:%s", cfg.proxy_username, cfg.proxy_password);	    len = strlen(buf);	    sprintf(buf2, "Proxy-Authorization: basic ");	    for (i = 0, j = strlen(buf2); i < len; i += 3, j += 4)		base64_encode_atom(buf+i, (len-i > 3 ? 3 : len-i), buf2+j);	    strcpy(buf2+j, "\r\n");	    sk_write(p->sub_socket, buf2, strlen(buf2));	}	sprintf(buf, "\r\n");	sk_write(p->sub_socket, buf, strlen(buf));	p->state = 1;	return 0;    }    if (change == PROXY_CHANGE_CLOSING) {	/* if our proxy negotiation process involves closing and opening	 * new sockets, then we would want to intercept this closing	 * callback when we were expecting it. if we aren't anticipating	 * a socket close, then some error must have occurred. we'll	 * just pass those errors up to the backend.	 */	return plug_closing(p->plug, p->closing_error_msg,			    p->closing_error_code,			    p->closing_calling_back);    }    if (change == PROXY_CHANGE_SENT) {	/* some (or all) of what we wrote to the proxy was sent.	 * we don't do anything new, however, until we receive the	 * proxy's response. we might want to set a timer so we can	 * timeout the proxy negotiation after a while...	 */	return 0;    }    if (change == PROXY_CHANGE_ACCEPTING) {	/* we should _never_ see this, as we are using our socket to	 * connect to a proxy, not accepting inbound connections.	 * what should we do? close the socket with an appropriate	 * error message?	 */	return plug_accepting(p->plug, p->accepting_sock);    }    if (change == PROXY_CHANGE_RECEIVE) {	/* we have received data from the underlying socket, which	 * we'll need to parse, process, and respond to appropriately.	 */	char *data, *datap;	int len;	int eol;	if (p->state == 1) {	    int min_ver, maj_ver, status;	    /* get the status line */	    len = bufchain_size(&p->pending_input_data);	    assert(len > 0);	       /* or we wouldn't be here */	    data = smalloc(len);	    bufchain_fetch(&p->pending_input_data, data, len);	    eol = get_line_end(data, len);	    if (eol < 0) {		sfree(data);		return 1;	    }	    status = -1;	    /* We can't rely on whether the %n incremented the sscanf return */	    if (sscanf((char *)data, "HTTP/%i.%i %n",		       &maj_ver, &min_ver, &status) < 2 || status == -1) {		plug_closing(p->plug, "Proxy error: HTTP response was absent",			     PROXY_ERROR_GENERAL, 0);		sfree(data);		return 1;	    }	    /* remove the status line from the input buffer. */	    bufchain_consume(&p->pending_input_data, eol);	    if (data[status] != '2') {		/* error */		char buf[1024];		data[eol] = '\0';		while (eol > status &&		       (data[eol-1] == '\r' || data[eol-1] == '\n'))		    data[--eol] = '\0';		sprintf(buf, "Proxy error: %.900s",			data+status);		plug_closing(p->plug, buf, PROXY_ERROR_GENERAL, 0);		sfree(data);		return 1;	    }	    sfree(data);	    p->state = 2;	}	if (p->state == 2) {	    /* get headers. we're done when we get a	     * header of length 2, (ie. just "\r\n")	     */	    len = bufchain_size(&p->pending_input_data);	    assert(len > 0);	       /* or we wouldn't be here */	    data = smalloc(len);	    datap = data;	    bufchain_fetch(&p->pending_input_data, data, len);	    eol = get_line_end(datap, len);	    if (eol < 0) {		sfree(data);		return 1;	    }	    while (eol > 2)	    {		bufchain_consume(&p->pending_input_data, eol);		datap += eol;		eol = get_line_end(datap, len);	    }	    if (eol == 2) {		/* we're done */		bufchain_consume(&p->pending_input_data, 2);		proxy_activate(p);		/* proxy activate will have dealt with		 * whatever is left of the buffer */		sfree(data);		return 1;	    }	    sfree(data);	    return 1;	}    }    plug_closing(p->plug, "Proxy error: unexpected proxy error",		 PROXY_ERROR_UNEXPECTED, 0);    return 1;}