X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Ffile.c;h=dd2c56498efc322b8ff0b4e09bfc17e9271992a9;hb=ff9f0eb35d80c251e9a54162eae18f44349ae59d;hp=038bf42e17b37785b9e5417cec6901623970a0b4;hpb=d69d98bb1e0435e6d0a6358677725bd663f598c0;p=platform%2Fupstream%2Fcurl.git diff --git a/lib/file.c b/lib/file.c index 038bf42..dd2c564 100644 --- a/lib/file.c +++ b/lib/file.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -90,7 +90,7 @@ static CURLcode file_done(struct connectdata *conn, static CURLcode file_connect(struct connectdata *conn, bool *done); static CURLcode file_disconnect(struct connectdata *conn, bool dead_connection); - +static CURLcode file_setup_connection(struct connectdata *conn); /* * FILE scheme handler. @@ -98,7 +98,7 @@ static CURLcode file_disconnect(struct connectdata *conn, const struct Curl_handler Curl_handler_file = { "FILE", /* scheme */ - ZERO_NULL, /* setup_connection */ + file_setup_connection, /* setup_connection */ file_do, /* do_it */ file_done, /* done */ ZERO_NULL, /* do_more */ @@ -117,6 +117,16 @@ const struct Curl_handler Curl_handler_file = { }; +static CURLcode file_setup_connection(struct connectdata *conn) +{ + /* allocate the FILE specific struct */ + conn->data->req.protop = calloc(1, sizeof(struct FILEPROTO)); + if(!conn->data->req.protop) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; +} + /* Check if this is a range download, and if so, set the internal variables properly. This code is copied from the FTP implementation and might as @@ -142,14 +152,14 @@ static CURLcode file_range(struct connectdata *conn) if((-1 == to) && (from>=0)) { /* X - */ data->state.resume_from = from; - DEBUGF(infof(data, "RANGE %" FORMAT_OFF_T " to end of file\n", + DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n", from)); } else if(from < 0) { /* -Y */ data->req.maxdownload = -from; data->state.resume_from = from; - DEBUGF(infof(data, "RANGE the last %" FORMAT_OFF_T " bytes\n", + DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n", -from)); } else { @@ -157,12 +167,13 @@ static CURLcode file_range(struct connectdata *conn) totalsize = to-from; data->req.maxdownload = totalsize+1; /* include last byte */ data->state.resume_from = from; - DEBUGF(infof(data, "RANGE from %" FORMAT_OFF_T - " getting %" FORMAT_OFF_T " bytes\n", + DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T + " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n", from, data->req.maxdownload)); } - DEBUGF(infof(data, "range-download from %" FORMAT_OFF_T - " to %" FORMAT_OFF_T ", totally %" FORMAT_OFF_T " bytes\n", + DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T + " to %" CURL_FORMAT_CURL_OFF_T ", totally %" + CURL_FORMAT_CURL_OFF_T " bytes\n", from, to, data->req.maxdownload)); } else @@ -179,39 +190,18 @@ static CURLcode file_connect(struct connectdata *conn, bool *done) { struct SessionHandle *data = conn->data; char *real_path; - struct FILEPROTO *file; + struct FILEPROTO *file = data->req.protop; int fd; #ifdef DOS_FILESYSTEM int i; char *actual_path; #endif + int real_path_len; - /* If there already is a protocol-specific struct allocated for this - sessionhandle, deal with it */ - Curl_reset_reqproto(conn); - - real_path = curl_easy_unescape(data, data->state.path, 0, NULL); + real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len); if(!real_path) return CURLE_OUT_OF_MEMORY; - if(!data->state.proto.file) { - file = calloc(1, sizeof(struct FILEPROTO)); - if(!file) { - free(real_path); - return CURLE_OUT_OF_MEMORY; - } - data->state.proto.file = file; - } - else { - /* file is not a protocol that can deal with "persistancy" */ - file = data->state.proto.file; - Curl_safefree(file->freepath); - file->path = NULL; - if(file->fd != -1) - close(file->fd); - file->fd = -1; - } - #ifdef DOS_FILESYSTEM /* If the first character is a slash, and there's something that looks like a drive at the beginning of @@ -233,16 +223,23 @@ static CURLcode file_connect(struct connectdata *conn, bool *done) (actual_path[2] == ':' || actual_path[2] == '|')) { actual_path[2] = ':'; actual_path++; + real_path_len--; } /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */ - for(i=0; actual_path[i] != '\0'; ++i) + for(i=0; i < real_path_len; ++i) if(actual_path[i] == '/') actual_path[i] = '\\'; + else if(!actual_path[i]) /* binary zero */ + return CURLE_URL_MALFORMAT; fd = open_readonly(actual_path, O_RDONLY|O_BINARY); file->path = actual_path; #else + if(memchr(real_path, 0, real_path_len)) + /* binary zeroes indicate foul play */ + return CURLE_URL_MALFORMAT; + fd = open_readonly(real_path, O_RDONLY); file->path = real_path; #endif @@ -262,7 +259,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done) static CURLcode file_done(struct connectdata *conn, CURLcode status, bool premature) { - struct FILEPROTO *file = conn->data->state.proto.file; + struct FILEPROTO *file = conn->data->req.protop; (void)status; /* not used */ (void)premature; /* not used */ @@ -280,7 +277,7 @@ static CURLcode file_done(struct connectdata *conn, static CURLcode file_disconnect(struct connectdata *conn, bool dead_connection) { - struct FILEPROTO *file = conn->data->state.proto.file; + struct FILEPROTO *file = conn->data->req.protop; (void)dead_connection; /* not used */ if(file) { @@ -302,11 +299,11 @@ static CURLcode file_disconnect(struct connectdata *conn, static CURLcode file_upload(struct connectdata *conn) { - struct FILEPROTO *file = conn->data->state.proto.file; + struct FILEPROTO *file = conn->data->req.protop; const char *dir = strchr(file->path, DIRSEP); int fd; int mode; - CURLcode res=CURLE_OK; + CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; char *buf = data->state.buffer; size_t nread; @@ -347,9 +344,9 @@ static CURLcode file_upload(struct connectdata *conn) return CURLE_WRITE_ERROR; } - if(-1 != data->set.infilesize) + if(-1 != data->state.infilesize) /* known size of data to "upload" */ - Curl_pgrsSetUploadSize(data, data->set.infilesize); + Curl_pgrsSetUploadSize(data, data->state.infilesize); /* treat the negative resume offset value as the case of "-" */ if(data->state.resume_from < 0) { @@ -362,10 +359,10 @@ static CURLcode file_upload(struct connectdata *conn) data->state.resume_from = (curl_off_t)file_stat.st_size; } - while(res == CURLE_OK) { + while(!result) { int readcount; - res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount); - if(res) + result = Curl_fillreadbuffer(conn, BUFSIZE, &readcount); + if(result) break; if(readcount <= 0) /* fix questionable compare error. curlvms */ @@ -392,7 +389,7 @@ static CURLcode file_upload(struct connectdata *conn) /* write the data to the target */ nwrite = write(fd, buf2, nread); if(nwrite != nread) { - res = CURLE_SEND_ERROR; + result = CURLE_SEND_ERROR; break; } @@ -401,16 +398,16 @@ static CURLcode file_upload(struct connectdata *conn) Curl_pgrsSetUploadCounter(data, bytecount); if(Curl_pgrsUpdate(conn)) - res = CURLE_ABORTED_BY_CALLBACK; + result = CURLE_ABORTED_BY_CALLBACK; else - res = Curl_speedcheck(data, now); + result = Curl_speedcheck(data, now); } - if(!res && Curl_pgrsUpdate(conn)) - res = CURLE_ABORTED_BY_CALLBACK; + if(!result && Curl_pgrsUpdate(conn)) + result = CURLE_ABORTED_BY_CALLBACK; close(fd); - return res; + return result; } /* @@ -428,7 +425,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done) are supported. This means that files on remotely mounted directories (via NFS, Samba, NT sharing) can be accessed through a file:// URL */ - CURLcode res = CURLE_OK; + CURLcode result = CURLE_OK; struct_stat statbuf; /* struct_stat instead of struct stat just to allow the Windows version to have a different struct without having to redefine the simple word 'stat' */ @@ -440,6 +437,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done) curl_off_t bytecount = 0; int fd; struct timeval now = Curl_tvnow(); + struct FILEPROTO *file; *done = TRUE; /* unconditionally */ @@ -449,8 +447,10 @@ static CURLcode file_do(struct connectdata *conn, bool *done) if(data->set.upload) return file_upload(conn); + file = conn->data->req.protop; + /* get the fd from the connection phase */ - fd = conn->data->state.proto.file->fd; + fd = file->fd; /* VMS: This only works reliable for STREAMLF files */ if(-1 != fstat(fd, &statbuf)) { @@ -472,9 +472,8 @@ static CURLcode file_do(struct connectdata *conn, bool *done) information. Which for FILE can't be much more than the file size and date. */ if(data->set.opt_no_body && data->set.include_header && fstated) { - CURLcode result; snprintf(buf, sizeof(data->state.buffer), - "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size); + "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size); result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0); if(result) return result; @@ -554,7 +553,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done) Curl_pgrsTime(data, TIMER_STARTTRANSFER); - while(res == CURLE_OK) { + while(!result) { /* Don't fill a whole buffer if we want less than all data */ size_t bytestoread = (expected_size < CURL_OFF_T_C(BUFSIZE) - CURL_OFF_T_C(1)) ? @@ -571,21 +570,21 @@ static CURLcode file_do(struct connectdata *conn, bool *done) bytecount += nread; expected_size -= nread; - res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread); - if(res) - return res; + result = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread); + if(result) + return result; Curl_pgrsSetDownloadCounter(data, bytecount); if(Curl_pgrsUpdate(conn)) - res = CURLE_ABORTED_BY_CALLBACK; + result = CURLE_ABORTED_BY_CALLBACK; else - res = Curl_speedcheck(data, now); + result = Curl_speedcheck(data, now); } if(Curl_pgrsUpdate(conn)) - res = CURLE_ABORTED_BY_CALLBACK; + result = CURLE_ABORTED_BY_CALLBACK; - return res; + return result; } #endif