curl/lib/sendf.c

307 lines
7.2 KiB
C
Raw Normal View History

1999-12-29 09:20:26 -05:00
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Curl.
*
* The Initial Developer of the Original Code is Daniel Stenberg.
*
* Portions created by the Initial Developer are Copyright (C) 1998.
* All Rights Reserved.
*
* ------------------------------------------------------------
* Main author:
2000-06-20 11:31:26 -04:00
* - Daniel Stenberg <daniel@haxx.se>
1999-12-29 09:20:26 -05:00
*
2000-06-20 11:31:26 -04:00
* http://curl.haxx.se
1999-12-29 09:20:26 -05:00
*
* $Source$
* $Revision$
* $Date$
* $Author$
* $State$
* $Locker$
*
* ------------------------------------------------------------
****************************************************************************/
#include "setup.h"
1999-12-29 09:20:26 -05:00
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
#endif
#include <curl/curl.h>
#include "urldata.h"
#include "sendf.h"
1999-12-29 09:20:26 -05:00
2000-10-12 04:22:16 -04:00
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
1999-12-29 09:20:26 -05:00
#include <curl/mprintf.h>
2000-09-21 04:49:16 -04:00
#ifdef KRB4
#include "security.h"
#endif
#include <string.h>
2000-10-09 07:12:34 -04:00
/* The last #include file should be: */
#ifdef MALLOCDEBUG
#include "memdebug.h"
#endif
2000-09-21 04:49:16 -04:00
1999-12-29 09:20:26 -05:00
/* infof() is for info message along the way */
void infof(struct UrlData *data, char *fmt, ...)
{
va_list ap;
2000-05-22 10:12:12 -04:00
if(data->bits.verbose) {
1999-12-29 09:20:26 -05:00
va_start(ap, fmt);
fputs("* ", data->err);
vfprintf(data->err, fmt, ap);
va_end(ap);
}
}
/* failf() is for messages stating why we failed, the LAST one will be
returned for the user (if requested) */
void failf(struct UrlData *data, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if(data->errorbuffer)
2000-10-12 04:22:16 -04:00
vsnprintf(data->errorbuffer, CURL_ERROR_SIZE, fmt, ap);
1999-12-29 09:20:26 -05:00
else /* no errorbuffer receives this, write to data->err instead */
vfprintf(data->err, fmt, ap);
va_end(ap);
}
/* sendf() sends the formated data to the server */
size_t sendf(int fd, struct UrlData *data, char *fmt, ...)
1999-12-29 09:20:26 -05:00
{
size_t bytes_written;
char *s;
va_list ap;
va_start(ap, fmt);
s = mvaprintf(fmt, ap);
va_end(ap);
if(!s)
return 0; /* failure */
2000-05-22 10:12:12 -04:00
if(data->bits.verbose)
1999-12-29 09:20:26 -05:00
fprintf(data->err, "> %s", s);
2000-09-21 04:49:16 -04:00
1999-12-29 09:20:26 -05:00
#ifndef USE_SSLEAY
2000-09-21 04:49:16 -04:00
bytes_written = swrite(fd, s, strlen(s));
#else /* USE_SSLEAY */
if (data->ssl.use) {
bytes_written = SSL_write(data->ssl.handle, s, strlen(s));
1999-12-29 09:20:26 -05:00
} else {
bytes_written = swrite(fd, s, strlen(s));
}
#endif /* USE_SSLEAY */
free(s); /* free the output string */
return(bytes_written);
}
2000-09-21 04:49:16 -04:00
/*
* ftpsendf() sends the formated string as a ftp command to a ftp server
*
* NOTE: we build the command in a fixed-length buffer, which sets length
* restrictions on the command!
*
2000-09-21 04:49:16 -04:00
*/
size_t ftpsendf(int fd, struct connectdata *conn, char *fmt, ...)
2000-09-21 04:49:16 -04:00
{
size_t bytes_written;
char s[256];
2000-09-21 04:49:16 -04:00
va_list ap;
va_start(ap, fmt);
vsnprintf(s, 250, fmt, ap);
2000-09-21 04:49:16 -04:00
va_end(ap);
2000-09-21 04:49:16 -04:00
if(conn->data->bits.verbose)
fprintf(conn->data->err, "> %s\n", s);
strcat(s, "\r\n"); /* append a trailing CRLF */
2000-09-21 04:49:16 -04:00
#ifdef KRB4
if(conn->sec_complete && conn->data->cmdchannel) {
bytes_written = sec_fprintf(conn, conn->data->cmdchannel, s);
fflush(conn->data->cmdchannel);
}
else
#endif /* KRB4 */
{
bytes_written = swrite(fd, s, strlen(s));
}
return(bytes_written);
}
2000-08-24 08:33:16 -04:00
/* ssend() sends plain (binary) data to the server */
2000-09-21 04:49:16 -04:00
size_t ssend(int fd, struct connectdata *conn, void *mem, size_t len)
2000-08-24 08:33:16 -04:00
{
size_t bytes_written;
2000-09-21 04:49:16 -04:00
struct UrlData *data=conn->data; /* conn knows data, not vice versa */
2000-08-24 08:33:16 -04:00
2000-09-21 04:49:16 -04:00
#ifdef USE_SSLEAY
if (data->ssl.use) {
bytes_written = SSL_write(data->ssl.handle, mem, len);
2000-08-24 08:33:16 -04:00
}
2000-09-21 04:49:16 -04:00
else {
#endif
#ifdef KRB4
if(conn->sec_complete) {
bytes_written = sec_write(conn, fd, mem, len);
}
else
#endif /* KRB4 */
bytes_written = swrite(fd, mem, len);
#ifdef USE_SSLEAY
}
#endif
2000-08-24 08:33:16 -04:00
return bytes_written;
}
2000-11-22 07:53:56 -05:00
/* client_write() sends data to the write callback(s)
The bit pattern defines to what "streams" to write to. Body and/or header.
The defines are in sendf.h of course.
*/
CURLcode client_write(struct UrlData *data,
int type,
char *ptr,
size_t len)
{
size_t wrote;
if(0 == len)
len = strlen(ptr);
if(type & CLIENTWRITE_BODY) {
wrote = data->fwrite(ptr, 1, len, data->out);
if(wrote != len) {
failf (data, "Failed writing body");
return CURLE_WRITE_ERROR;
}
}
if((type & CLIENTWRITE_HEADER) && data->writeheader) {
wrote = data->fwrite(ptr, 1, len, data->writeheader);
if(wrote != len) {
failf (data, "Failed writing header");
return CURLE_WRITE_ERROR;
}
}
return CURLE_OK;
}
/*
* add_buffer_init() returns a fine buffer struct
*/
send_buffer *add_buffer_init(void)
{
send_buffer *blonk;
blonk=(send_buffer *)malloc(sizeof(send_buffer));
if(blonk) {
memset(blonk, 0, sizeof(send_buffer));
return blonk;
}
return NULL; /* failed, go home */
}
/*
* add_buffer_send() sends a buffer and frees all associated memory.
*/
size_t add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in)
{
size_t amount;
if(conn->data->bits.verbose) {
fputs("> ", conn->data->err);
/* this data _may_ contain binary stuff */
fwrite(in->buffer, in->size_used, 1, conn->data->err);
}
1999-12-29 09:20:26 -05:00
amount = ssend(sockfd, conn, in->buffer, in->size_used);
if(in->buffer)
free(in->buffer);
free(in);
return amount;
}
1999-12-29 09:20:26 -05:00
/*
* add_bufferf() builds a buffer from the formatted input
*/
CURLcode add_bufferf(send_buffer *in, char *fmt, ...)
{
CURLcode result = CURLE_OUT_OF_MEMORY;
char *s;
va_list ap;
va_start(ap, fmt);
s = mvaprintf(fmt, ap); /* this allocs a new string to append */
va_end(ap);
if(s) {
result = add_buffer(in, s, strlen(s));
free(s);
}
return result;
}
/*
* add_buffer() appends a memory chunk to the existing one
*/
CURLcode add_buffer(send_buffer *in, void *inptr, size_t size)
{
char *new_rb;
int new_size;
if(size > 0) {
if(!in->buffer ||
((in->size_used + size) > (in->size_max - 1))) {
new_size = (in->size_used+size)*2;
if(in->buffer)
/* we have a buffer, enlarge the existing one */
new_rb = (char *)realloc(in->buffer, new_size);
else
/* create a new buffer */
new_rb = (char *)malloc(new_size);
if(!new_rb)
return CURLE_OUT_OF_MEMORY;
in->buffer = new_rb;
in->size_max = new_size;
}
memcpy(&in->buffer[in->size_used], inptr, size);
in->size_used += size;
}
return CURLE_OK;
}