示例#1
0
文件: file.c 项目: 2px/curl
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;
}
示例#2
0
文件: file.c 项目: 0w/moai-dev
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;
}
示例#3
0
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;
}