static CURLcode file_upload(struct connectdata *conn) { struct FILEPROTO *file = conn->data->req.protop; const char *dir = strchr(file->path, DIRSEP); int fd; int mode; CURLcode result = CURLE_OK; struct Curl_easy *data = conn->data; char *buf = data->state.buffer; size_t nread; size_t nwrite; curl_off_t bytecount = 0; struct timeval now = Curl_tvnow(); struct_stat file_stat; const char* buf2; /* * Since FILE: doesn't do the full init, we need to provide some extra * assignments here. */ conn->data->req.upload_fromhere = buf; if(!dir) return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ if(!dir[1]) return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ #ifdef O_BINARY #define MODE_DEFAULT O_WRONLY|O_CREAT|O_BINARY #else #define MODE_DEFAULT O_WRONLY|O_CREAT #endif if(data->state.resume_from) mode = MODE_DEFAULT|O_APPEND; else mode = MODE_DEFAULT|O_TRUNC; fd = open(file->path, mode, conn->data->set.new_file_perms); if(fd < 0) { failf(data, "Can't open %s for writing", file->path); return CURLE_WRITE_ERROR; } if(-1 != data->state.infilesize) /* known size of data to "upload" */ Curl_pgrsSetUploadSize(data, data->state.infilesize); /* treat the negative resume offset value as the case of "-" */ if(data->state.resume_from < 0) { if(fstat(fd, &file_stat)) { close(fd); failf(data, "Can't get the size of %s", file->path); return CURLE_WRITE_ERROR; } else data->state.resume_from = (curl_off_t)file_stat.st_size; } while(!result) { int readcount; result = Curl_fillreadbuffer(conn, BUFSIZE, &readcount); if(result) break; if(readcount <= 0) /* fix questionable compare error. curlvms */ break; nread = (size_t)readcount; /*skip bytes before resume point*/ if(data->state.resume_from) { if((curl_off_t)nread <= data->state.resume_from) { data->state.resume_from -= nread; nread = 0; buf2 = buf; } else { buf2 = buf + data->state.resume_from; nread -= (size_t)data->state.resume_from; data->state.resume_from = 0; } } else buf2 = buf; /* write the data to the target */ nwrite = write(fd, buf2, nread); if(nwrite != nread) { result = CURLE_SEND_ERROR; break; } bytecount += nread; Curl_pgrsSetUploadCounter(data, bytecount); if(Curl_pgrsUpdate(conn)) result = CURLE_ABORTED_BY_CALLBACK; else result = Curl_speedcheck(data, now); } if(!result && Curl_pgrsUpdate(conn)) result = CURLE_ABORTED_BY_CALLBACK; close(fd); return result; }
static CURLcode file_upload(struct connectdata *conn) { struct FILEPROTO *file = conn->data->state.proto.file; const char *dir = strchr(file->path, DIRSEP); FILE *fp; CURLcode res=CURLE_OK; struct SessionHandle *data = conn->data; char *buf = data->state.buffer; size_t nread; size_t nwrite; curl_off_t bytecount = 0; struct timeval now = Curl_tvnow(); struct_stat file_stat; const char* buf2; /* * Since FILE: doesn't do the full init, we need to provide some extra * assignments here. */ conn->fread_func = data->set.fread_func; conn->fread_in = data->set.in; conn->data->req.upload_fromhere = buf; if(!dir) return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ if(!dir[1]) return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ if(data->state.resume_from) fp = fopen( file->path, "ab" ); else { int fd; #ifdef DOS_FILESYSTEM fd = open(file->path, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, conn->data->set.new_file_perms); #else fd = open(file->path, O_WRONLY|O_CREAT|O_TRUNC, conn->data->set.new_file_perms); #endif if(fd < 0) { failf(data, "Can't open %s for writing", file->path); return CURLE_WRITE_ERROR; } close(fd); fp = fopen(file->path, "wb"); } if(!fp) { failf(data, "Can't open %s for writing", file->path); return CURLE_WRITE_ERROR; } if(-1 != data->set.infilesize) /* known size of data to "upload" */ Curl_pgrsSetUploadSize(data, data->set.infilesize); /* treat the negative resume offset value as the case of "-" */ if(data->state.resume_from < 0) { if(fstat(fileno(fp), &file_stat)) { fclose(fp); failf(data, "Can't get the size of %s", file->path); return CURLE_WRITE_ERROR; } else data->state.resume_from = (curl_off_t)file_stat.st_size; } while(res == CURLE_OK) { int readcount; res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount); if(res) break; if(readcount <= 0) /* fix questionable compare error. curlvms */ break; nread = (size_t)readcount; /*skip bytes before resume point*/ if(data->state.resume_from) { if( (curl_off_t)nread <= data->state.resume_from ) { data->state.resume_from -= nread; nread = 0; buf2 = buf; } else { buf2 = buf + data->state.resume_from; nread -= (size_t)data->state.resume_from; data->state.resume_from = 0; } } else buf2 = buf; /* write the data to the target */ nwrite = fwrite(buf2, 1, nread, fp); if(nwrite != nread) { res = CURLE_SEND_ERROR; break; } bytecount += nread; Curl_pgrsSetUploadCounter(data, bytecount); if(Curl_pgrsUpdate(conn)) res = CURLE_ABORTED_BY_CALLBACK; else res = Curl_speedcheck(data, now); } if(!res && Curl_pgrsUpdate(conn)) res = CURLE_ABORTED_BY_CALLBACK; fclose(fp); return res; }
static CURLcode file_upload(struct connectdata *conn) { struct FILEPROTO *file = conn->proto.file; char *dir = strchr(file->path, DIRSEP); FILE *fp; CURLcode res=CURLE_OK; struct SessionHandle *data = conn->data; char *buf = data->state.buffer; size_t nread; size_t nwrite; curl_off_t bytecount = 0; struct timeval now = Curl_tvnow(); /* * Since FILE: doesn't do the full init, we need to provide some extra * assignments here. */ conn->fread = data->set.fread; conn->fread_in = data->set.in; conn->upload_fromhere = buf; if(!dir) return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ if(!dir[1]) return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ fp = fopen(file->path, "wb"); if(!fp) { failf(data, "Can't open %s for writing", file->path); return CURLE_WRITE_ERROR; } if(-1 != data->set.infilesize) /* known size of data to "upload" */ Curl_pgrsSetUploadSize(data, data->set.infilesize); while (res == CURLE_OK) { int readcount; res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount); if(res) break; nread = (size_t)readcount; if (nread <= 0) break; /* write the data to the target */ nwrite = fwrite(buf, 1, nread, fp); if(nwrite != nread) { res = CURLE_SEND_ERROR; break; } bytecount += nread; Curl_pgrsSetUploadCounter(data, bytecount); if(Curl_pgrsUpdate(conn)) res = CURLE_ABORTED_BY_CALLBACK; else res = Curl_speedcheck(data, now); } if(!res && Curl_pgrsUpdate(conn)) res = CURLE_ABORTED_BY_CALLBACK; fclose(fp); return res; }