compiler warning: fix
[platform/upstream/curl.git] / lib / sendf.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at http://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22
23 #include "setup.h"
24
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <errno.h>
29
30 #ifdef HAVE_SYS_SOCKET_H
31 #include <sys/socket.h> /* required for send() & recv() prototypes */
32 #endif
33
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #include <curl/curl.h>
39 #include "urldata.h"
40 #include "sendf.h"
41 #include "connect.h"
42 #include "sslgen.h"
43 #include "ssh.h"
44 #include "multiif.h"
45 #include "non-ascii.h"
46
47 #define _MPRINTF_REPLACE /* use the internal *printf() functions */
48 #include <curl/mprintf.h>
49
50 /* the krb4 functions only exists for FTP and if krb4 or gssapi is defined */
51 #if !defined(CURL_DISABLE_FTP) && (defined(HAVE_KRB4) || defined(HAVE_GSSAPI))
52 #include "krb4.h"
53 #else
54 #define Curl_sec_send(a,b,c,d) -1
55 #define Curl_sec_read(a,b,c,d) -1
56 #endif
57
58 #include <string.h>
59 #include "curl_memory.h"
60 #include "strerror.h"
61
62 /* The last #include file should be: */
63 #include "memdebug.h"
64
65 #ifdef CURL_DO_LINEEND_CONV
66 /*
67  * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
68  * (\n), with special processing for CRLF sequences that are split between two
69  * blocks of data.  Remaining, bare CRs are changed to LFs.  The possibly new
70  * size of the data is returned.
71  */
72 static size_t convert_lineends(struct SessionHandle *data,
73                                char *startPtr, size_t size)
74 {
75   char *inPtr, *outPtr;
76
77   /* sanity check */
78   if((startPtr == NULL) || (size < 1)) {
79     return(size);
80   }
81
82   if(data->state.prev_block_had_trailing_cr == TRUE) {
83     /* The previous block of incoming data
84        had a trailing CR, which was turned into a LF. */
85     if(*startPtr == '\n') {
86       /* This block of incoming data starts with the
87          previous block's LF so get rid of it */
88       memmove(startPtr, startPtr+1, size-1);
89       size--;
90       /* and it wasn't a bare CR but a CRLF conversion instead */
91       data->state.crlf_conversions++;
92     }
93     data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
94   }
95
96   /* find 1st CR, if any */
97   inPtr = outPtr = memchr(startPtr, '\r', size);
98   if(inPtr) {
99     /* at least one CR, now look for CRLF */
100     while(inPtr < (startPtr+size-1)) {
101       /* note that it's size-1, so we'll never look past the last byte */
102       if(memcmp(inPtr, "\r\n", 2) == 0) {
103         /* CRLF found, bump past the CR and copy the NL */
104         inPtr++;
105         *outPtr = *inPtr;
106         /* keep track of how many CRLFs we converted */
107         data->state.crlf_conversions++;
108       }
109       else {
110         if(*inPtr == '\r') {
111           /* lone CR, move LF instead */
112           *outPtr = '\n';
113         }
114         else {
115           /* not a CRLF nor a CR, just copy whatever it is */
116           *outPtr = *inPtr;
117         }
118       }
119       outPtr++;
120       inPtr++;
121     } /* end of while loop */
122
123     if(inPtr < startPtr+size) {
124       /* handle last byte */
125       if(*inPtr == '\r') {
126         /* deal with a CR at the end of the buffer */
127         *outPtr = '\n'; /* copy a NL instead */
128         /* note that a CRLF might be split across two blocks */
129         data->state.prev_block_had_trailing_cr = TRUE;
130       }
131       else {
132         /* copy last byte */
133         *outPtr = *inPtr;
134       }
135       outPtr++;
136     }
137     if(outPtr < startPtr+size)
138       /* tidy up by null terminating the now shorter data */
139       *outPtr = '\0';
140
141     return(outPtr - startPtr);
142   }
143   return(size);
144 }
145 #endif /* CURL_DO_LINEEND_CONV */
146
147 /* Curl_infof() is for info message along the way */
148
149 void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
150 {
151   if(data && data->set.verbose) {
152     va_list ap;
153     size_t len;
154     char print_buffer[2048 + 1];
155     va_start(ap, fmt);
156     vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
157     va_end(ap);
158     len = strlen(print_buffer);
159     Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
160   }
161 }
162
163 /* Curl_failf() is for messages stating why we failed.
164  * The message SHALL NOT include any LF or CR.
165  */
166
167 void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
168 {
169   va_list ap;
170   size_t len;
171   va_start(ap, fmt);
172
173   vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
174
175   if(data->set.errorbuffer && !data->state.errorbuf) {
176     snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);
177     data->state.errorbuf = TRUE; /* wrote error string */
178   }
179   if(data->set.verbose) {
180     len = strlen(data->state.buffer);
181     if(len < BUFSIZE - 1) {
182       data->state.buffer[len] = '\n';
183       data->state.buffer[++len] = '\0';
184     }
185     Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
186   }
187
188   va_end(ap);
189 }
190
191 /* Curl_sendf() sends formated data to the server */
192 CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
193                     const char *fmt, ...)
194 {
195   struct SessionHandle *data = conn->data;
196   ssize_t bytes_written;
197   size_t write_len;
198   CURLcode res = CURLE_OK;
199   char *s;
200   char *sptr;
201   va_list ap;
202   va_start(ap, fmt);
203   s = vaprintf(fmt, ap); /* returns an allocated string */
204   va_end(ap);
205   if(!s)
206     return CURLE_OUT_OF_MEMORY; /* failure */
207
208   bytes_written=0;
209   write_len = strlen(s);
210   sptr = s;
211
212   for(;;) {
213     /* Write the buffer to the socket */
214     res = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
215
216     if(CURLE_OK != res)
217       break;
218
219     if(data->set.verbose)
220       Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
221
222     if((size_t)bytes_written != write_len) {
223       /* if not all was written at once, we must advance the pointer, decrease
224          the size left and try again! */
225       write_len -= bytes_written;
226       sptr += bytes_written;
227     }
228     else
229       break;
230   }
231
232   free(s); /* free the output string */
233
234   return res;
235 }
236
237 /*
238  * Curl_write() is an internal write function that sends data to the
239  * server. Works with plain sockets, SCP, SSL or kerberos.
240  *
241  * If the write would block (CURLE_AGAIN), we return CURLE_OK and
242  * (*written == 0). Otherwise we return regular CURLcode value.
243  */
244 CURLcode Curl_write(struct connectdata *conn,
245                     curl_socket_t sockfd,
246                     const void *mem,
247                     size_t len,
248                     ssize_t *written)
249 {
250   ssize_t bytes_written;
251   CURLcode curlcode = CURLE_OK;
252   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
253
254   bytes_written = conn->send[num](conn, num, mem, len, &curlcode);
255
256   *written = bytes_written;
257   if(bytes_written >= 0)
258     /* we completely ignore the curlcode value when subzero is not returned */
259     return CURLE_OK;
260
261   /* handle CURLE_AGAIN or a send failure */
262   switch(curlcode) {
263   case CURLE_AGAIN:
264     *written = 0;
265     return CURLE_OK;
266
267   case CURLE_OK:
268     /* general send failure */
269     return CURLE_SEND_ERROR;
270
271   default:
272     /* we got a specific curlcode, forward it */
273     return (CURLcode)curlcode;
274   }
275 }
276
277 ssize_t Curl_send_plain(struct connectdata *conn, int num,
278                         const void *mem, size_t len, CURLcode *code)
279 {
280   curl_socket_t sockfd = conn->sock[num];
281   ssize_t bytes_written = swrite(sockfd, mem, len);
282
283   *code = CURLE_OK;
284   if(-1 == bytes_written) {
285     int err = SOCKERRNO;
286
287     if(
288 #ifdef WSAEWOULDBLOCK
289       /* This is how Windows does it */
290       (WSAEWOULDBLOCK == err)
291 #else
292       /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
293          due to its inability to send off data without blocking. We therefor
294          treat both error codes the same here */
295       (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
296 #endif
297       ) {
298       /* this is just a case of EWOULDBLOCK */
299       bytes_written=0;
300       *code = CURLE_AGAIN;
301     }
302     else {
303       failf(conn->data, "Send failure: %s",
304             Curl_strerror(conn, err));
305       conn->data->state.os_errno = err;
306       *code = CURLE_SEND_ERROR;
307     }
308   }
309   return bytes_written;
310 }
311
312 /*
313  * Curl_write_plain() is an internal write function that sends data to the
314  * server using plain sockets only. Otherwise meant to have the exact same
315  * proto as Curl_write()
316  */
317 CURLcode Curl_write_plain(struct connectdata *conn,
318                           curl_socket_t sockfd,
319                           const void *mem,
320                           size_t len,
321                           ssize_t *written)
322 {
323   ssize_t bytes_written;
324   CURLcode retcode;
325   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
326
327   bytes_written = Curl_send_plain(conn, num, mem, len, &retcode);
328
329   *written = bytes_written;
330
331   return retcode;
332 }
333
334 ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
335                         size_t len, CURLcode *code)
336 {
337   curl_socket_t sockfd = conn->sock[num];
338   ssize_t nread = sread(sockfd, buf, len);
339
340   *code = CURLE_OK;
341   if(-1 == nread) {
342     int err = SOCKERRNO;
343
344     if(
345 #ifdef WSAEWOULDBLOCK
346       /* This is how Windows does it */
347       (WSAEWOULDBLOCK == err)
348 #else
349       /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
350          due to its inability to send off data without blocking. We therefor
351          treat both error codes the same here */
352       (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
353 #endif
354       ) {
355       /* this is just a case of EWOULDBLOCK */
356       *code = CURLE_AGAIN;
357     }
358     else {
359       failf(conn->data, "Recv failure: %s",
360             Curl_strerror(conn, err));
361       conn->data->state.os_errno = err;
362       *code = CURLE_RECV_ERROR;
363     }
364   }
365   return nread;
366 }
367
368 static CURLcode pausewrite(struct SessionHandle *data,
369                            int type, /* what type of data */
370                            const char *ptr,
371                            size_t len)
372 {
373   /* signalled to pause sending on this connection, but since we have data
374      we want to send we need to dup it to save a copy for when the sending
375      is again enabled */
376   struct SingleRequest *k = &data->req;
377   char *dupl = malloc(len);
378   if(!dupl)
379     return CURLE_OUT_OF_MEMORY;
380
381   memcpy(dupl, ptr, len);
382
383   /* store this information in the state struct for later use */
384   data->state.tempwrite = dupl;
385   data->state.tempwritesize = len;
386   data->state.tempwritetype = type;
387
388   /* mark the connection as RECV paused */
389   k->keepon |= KEEP_RECV_PAUSE;
390
391   DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n",
392                len, type));
393
394   return CURLE_OK;
395 }
396
397
398 /* Curl_client_write() sends data to the write callback(s)
399
400    The bit pattern defines to what "streams" to write to. Body and/or header.
401    The defines are in sendf.h of course.
402
403    If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
404    local character encoding.  This is a problem and should be changed in
405    the future to leave the original data alone.
406  */
407 CURLcode Curl_client_write(struct connectdata *conn,
408                            int type,
409                            char *ptr,
410                            size_t len)
411 {
412   struct SessionHandle *data = conn->data;
413   size_t wrote;
414
415   if(0 == len)
416     len = strlen(ptr);
417
418   /* If reading is actually paused, we're forced to append this chunk of data
419      to the already held data, but only if it is the same type as otherwise it
420      can't work and it'll return error instead. */
421   if(data->req.keepon & KEEP_RECV_PAUSE) {
422     size_t newlen;
423     char *newptr;
424     if(type != data->state.tempwritetype)
425       /* major internal confusion */
426       return CURLE_RECV_ERROR;
427
428     DEBUGASSERT(data->state.tempwrite);
429
430     /* figure out the new size of the data to save */
431     newlen = len + data->state.tempwritesize;
432     /* allocate the new memory area */
433     newptr = realloc(data->state.tempwrite, newlen);
434     if(!newptr)
435       return CURLE_OUT_OF_MEMORY;
436     /* copy the new data to the end of the new area */
437     memcpy(newptr + data->state.tempwritesize, ptr, len);
438     /* update the pointer and the size */
439     data->state.tempwrite = newptr;
440     data->state.tempwritesize = newlen;
441
442     return CURLE_OK;
443   }
444
445   if(type & CLIENTWRITE_BODY) {
446     if((conn->handler->protocol&CURLPROTO_FTP) &&
447        conn->proto.ftpc.transfertype == 'A') {
448       /* convert from the network encoding */
449       CURLcode rc = Curl_convert_from_network(data, ptr, len);
450       /* Curl_convert_from_network calls failf if unsuccessful */
451       if(rc)
452         return rc;
453
454 #ifdef CURL_DO_LINEEND_CONV
455       /* convert end-of-line markers */
456       len = convert_lineends(data, ptr, len);
457 #endif /* CURL_DO_LINEEND_CONV */
458     }
459     /* If the previous block of data ended with CR and this block of data is
460        just a NL, then the length might be zero */
461     if(len) {
462       wrote = data->set.fwrite_func(ptr, 1, len, data->set.out);
463     }
464     else {
465       wrote = len;
466     }
467
468     if(CURL_WRITEFUNC_PAUSE == wrote)
469       return pausewrite(data, type, ptr, len);
470
471     if(wrote != len) {
472       failf(data, "Failed writing body (%zu != %zu)", wrote, len);
473       return CURLE_WRITE_ERROR;
474     }
475   }
476
477   if((type & CLIENTWRITE_HEADER) &&
478      (data->set.fwrite_header || data->set.writeheader) ) {
479     /*
480      * Write headers to the same callback or to the especially setup
481      * header callback function (added after version 7.7.1).
482      */
483     curl_write_callback writeit=
484       data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite_func;
485
486     /* Note: The header is in the host encoding
487        regardless of the ftp transfer mode (ASCII/Image) */
488
489     wrote = writeit(ptr, 1, len, data->set.writeheader);
490     if(CURL_WRITEFUNC_PAUSE == wrote)
491       /* here we pass in the HEADER bit only since if this was body as well
492          then it was passed already and clearly that didn't trigger the pause,
493          so this is saved for later with the HEADER bit only */
494       return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
495
496     if(wrote != len) {
497       failf (data, "Failed writing header");
498       return CURLE_WRITE_ERROR;
499     }
500   }
501
502   return CURLE_OK;
503 }
504
505 CURLcode Curl_read_plain(curl_socket_t sockfd,
506                          char *buf,
507                          size_t bytesfromsocket,
508                          ssize_t *n)
509 {
510   ssize_t nread = sread(sockfd, buf, bytesfromsocket);
511
512   if(-1 == nread) {
513     int err = SOCKERRNO;
514 #ifdef USE_WINSOCK
515     if(WSAEWOULDBLOCK == err)
516 #else
517     if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
518 #endif
519       return CURLE_AGAIN;
520     else
521       return CURLE_RECV_ERROR;
522   }
523
524   /* we only return number of bytes read when we return OK */
525   *n = nread;
526   return CURLE_OK;
527 }
528
529 /*
530  * Internal read-from-socket function. This is meant to deal with plain
531  * sockets, SSL sockets and kerberos sockets.
532  *
533  * Returns a regular CURLcode value.
534  */
535 CURLcode Curl_read(struct connectdata *conn, /* connection data */
536               curl_socket_t sockfd,     /* read from this socket */
537               char *buf,                /* store read data here */
538               size_t sizerequested,     /* max amount to read */
539               ssize_t *n)               /* amount bytes read */
540 {
541   CURLcode curlcode = CURLE_RECV_ERROR;
542   ssize_t nread = 0;
543   size_t bytesfromsocket = 0;
544   char *buffertofill = NULL;
545   bool pipelining = (bool)(conn->data->multi &&
546                      Curl_multi_canPipeline(conn->data->multi));
547
548   /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
549      If it is the second socket, we set num to 1. Otherwise to 0. This lets
550      us use the correct ssl handle. */
551   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
552
553   *n=0; /* reset amount to zero */
554
555   /* If session can pipeline, check connection buffer  */
556   if(pipelining) {
557     size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
558                                  sizerequested);
559
560     /* Copy from our master buffer first if we have some unread data there*/
561     if(bytestocopy > 0) {
562       memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
563       conn->read_pos += bytestocopy;
564       conn->bits.stream_was_rewound = FALSE;
565
566       *n = (ssize_t)bytestocopy;
567       return CURLE_OK;
568     }
569     /* If we come here, it means that there is no data to read from the buffer,
570      * so we read from the socket */
571     bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char));
572     buffertofill = conn->master_buffer;
573   }
574   else {
575     bytesfromsocket = CURLMIN((long)sizerequested,
576                               conn->data->set.buffer_size ?
577                               conn->data->set.buffer_size : BUFSIZE);
578     buffertofill = buf;
579   }
580
581   nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &curlcode);
582   if(nread < 0)
583     return curlcode;
584
585   if(pipelining) {
586     memcpy(buf, conn->master_buffer, nread);
587     conn->buf_len = nread;
588     conn->read_pos = nread;
589   }
590
591   *n += nread;
592
593   return CURLE_OK;
594 }
595
596 /* return 0 on success */
597 static int showit(struct SessionHandle *data, curl_infotype type,
598                   char *ptr, size_t size)
599 {
600   static const char s_infotype[CURLINFO_END][3] = {
601     "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
602
603 #ifdef CURL_DOES_CONVERSIONS
604   char buf[BUFSIZE+1];
605   size_t conv_size = 0;
606
607   switch(type) {
608   case CURLINFO_HEADER_OUT:
609     /* assume output headers are ASCII */
610     /* copy the data into my buffer so the original is unchanged */
611     if(size > BUFSIZE) {
612       size = BUFSIZE; /* truncate if necessary */
613       buf[BUFSIZE] = '\0';
614     }
615     conv_size = size;
616     memcpy(buf, ptr, size);
617     /* Special processing is needed for this block if it
618      * contains both headers and data (separated by CRLFCRLF).
619      * We want to convert just the headers, leaving the data as-is.
620      */
621     if(size > 4) {
622       size_t i;
623       for(i = 0; i < size-4; i++) {
624         if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
625           /* convert everything through this CRLFCRLF but no further */
626           conv_size = i + 4;
627           break;
628         }
629       }
630     }
631
632     Curl_convert_from_network(data, buf, conv_size);
633     /* Curl_convert_from_network calls failf if unsuccessful */
634     /* we might as well continue even if it fails...   */
635     ptr = buf; /* switch pointer to use my buffer instead */
636     break;
637   default:
638     /* leave everything else as-is */
639     break;
640   }
641 #endif /* CURL_DOES_CONVERSIONS */
642
643   if(data->set.fdebug)
644     return (*data->set.fdebug)(data, type, ptr, size,
645                                data->set.debugdata);
646
647   switch(type) {
648   case CURLINFO_TEXT:
649   case CURLINFO_HEADER_OUT:
650   case CURLINFO_HEADER_IN:
651     fwrite(s_infotype[type], 2, 1, data->set.err);
652     fwrite(ptr, size, 1, data->set.err);
653 #ifdef CURL_DOES_CONVERSIONS
654     if(size != conv_size) {
655       /* we had untranslated data so we need an explicit newline */
656       fwrite("\n", 1, 1, data->set.err);
657     }
658 #endif
659     break;
660   default: /* nada */
661     break;
662   }
663   return 0;
664 }
665
666 int Curl_debug(struct SessionHandle *data, curl_infotype type,
667                char *ptr, size_t size,
668                struct connectdata *conn)
669 {
670   int rc;
671   if(data->set.printhost && conn && conn->host.dispname) {
672     char buffer[160];
673     const char *t=NULL;
674     const char *w="Data";
675     switch (type) {
676     case CURLINFO_HEADER_IN:
677       w = "Header";
678     case CURLINFO_DATA_IN:
679       t = "from";
680       break;
681     case CURLINFO_HEADER_OUT:
682       w = "Header";
683     case CURLINFO_DATA_OUT:
684       t = "to";
685       break;
686     default:
687       break;
688     }
689
690     if(t) {
691       snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
692                conn->host.dispname);
693       rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
694       if(rc)
695         return rc;
696     }
697   }
698   rc = showit(data, type, ptr, size);
699   return rc;
700 }