Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "tool_setup.h"
00023
00024 #define ENABLE_CURLX_PRINTF
00025
00026 #include "curlx.h"
00027
00028 #include "tool_cfgable.h"
00029 #include "tool_msgs.h"
00030 #include "tool_cb_wrt.h"
00031
00032 #include "memdebug.h"
00033
00034
00035 bool tool_create_output_file(struct OutStruct *outs)
00036 {
00037 struct GlobalConfig *global = outs->config->global;
00038 FILE *file;
00039
00040 if(!outs->filename || !*outs->filename) {
00041 warnf(global, "Remote filename has no length!\n");
00042 return FALSE;
00043 }
00044
00045 if(outs->is_cd_filename) {
00046
00047 file = fopen(outs->filename, "rb");
00048 if(file) {
00049 fclose(file);
00050 warnf(global, "Refusing to overwrite %s: %s\n", outs->filename,
00051 strerror(EEXIST));
00052 return FALSE;
00053 }
00054 }
00055
00056
00057 file = fopen(outs->filename, "wb");
00058 if(!file) {
00059 warnf(global, "Failed to create the file %s: %s\n", outs->filename,
00060 strerror(errno));
00061 return FALSE;
00062 }
00063 outs->s_isreg = TRUE;
00064 outs->fopened = TRUE;
00065 outs->stream = file;
00066 outs->bytes = 0;
00067 outs->init = 0;
00068 return TRUE;
00069 }
00070
00071
00072
00073
00074
00075 size_t tool_write_cb(void *buffer, size_t sz, size_t nmemb, void *userdata)
00076 {
00077 size_t rc;
00078 struct OutStruct *outs = userdata;
00079 struct OperationConfig *config = outs->config;
00080
00081
00082
00083
00084
00085
00086
00087 const size_t failure = (sz * nmemb) ? 0 : 1;
00088
00089 if(!config)
00090 return failure;
00091
00092 #ifdef DEBUGBUILD
00093 if(config->include_headers) {
00094 if(sz * nmemb > (size_t)CURL_MAX_HTTP_HEADER) {
00095 warnf(config->global, "Header data size exceeds single call write "
00096 "limit!\n");
00097 return failure;
00098 }
00099 }
00100 else {
00101 if(sz * nmemb > (size_t)CURL_MAX_WRITE_SIZE) {
00102 warnf(config->global, "Data size exceeds single call write limit!\n");
00103 return failure;
00104 }
00105 }
00106
00107 {
00108
00109 bool check_fails = FALSE;
00110 if(outs->filename) {
00111
00112 if(!*outs->filename)
00113 check_fails = TRUE;
00114 if(!outs->s_isreg)
00115 check_fails = TRUE;
00116 if(outs->fopened && !outs->stream)
00117 check_fails = TRUE;
00118 if(!outs->fopened && outs->stream)
00119 check_fails = TRUE;
00120 if(!outs->fopened && outs->bytes)
00121 check_fails = TRUE;
00122 }
00123 else {
00124
00125 if(!outs->stream || outs->s_isreg || outs->fopened)
00126 check_fails = TRUE;
00127 if(outs->alloc_filename || outs->is_cd_filename || outs->init)
00128 check_fails = TRUE;
00129 }
00130 if(check_fails) {
00131 warnf(config->global, "Invalid output struct data for write callback\n");
00132 return failure;
00133 }
00134 }
00135 #endif
00136
00137 if(!outs->stream && !tool_create_output_file(outs))
00138 return failure;
00139
00140 rc = fwrite(buffer, sz, nmemb, outs->stream);
00141
00142 if((sz * nmemb) == rc)
00143
00144 outs->bytes += (sz * nmemb);
00145
00146 if(config->readbusy) {
00147 config->readbusy = FALSE;
00148 curl_easy_pause(config->easy, CURLPAUSE_CONT);
00149 }
00150
00151 if(config->nobuffer) {
00152
00153 int res = fflush(outs->stream);
00154 if(res)
00155 return failure;
00156 }
00157
00158 return rc;
00159 }