~ubuntu-branches/ubuntu/hoary/curl/hoary-security

« back to all changes in this revision

Viewing changes to lib/file.c

  • Committer: Bazaar Package Importer
  • Author(s): Domenico Andreoli
  • Date: 2004-06-04 19:09:25 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040604190925-wy048bp31320r2z6
Tags: 7.12.0.is.7.11.2-1
* Reverted to version 7.11.2 (closes: #252348).
* Disabled support for libidn (closes: #252367). This is to leave
  curl in unstable as much similar as possible to the one in testing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
 
1
/***************************************************************************
2
2
 *                                  _   _ ____  _     
3
3
 *  Project                     ___| | | |  _ \| |    
4
4
 *                             / __| | | | |_) | |    
5
5
 *                            | (__| |_| |  _ <| |___ 
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
9
 
 *
10
 
 * In order to be useful for every potential user, curl and libcurl are
11
 
 * dual-licensed under the MPL and the MIT/X-derivate licenses.
12
 
 *
 
8
 * Copyright (C) 1998 - 2004, 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
 * 
13
14
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
14
15
 * copies of the Software, and permit persons to whom the Software is
15
 
 * furnished to do so, under the terms of the MPL or the MIT/X-derivate
16
 
 * licenses. You may pick one of these licenses.
 
16
 * furnished to do so, under the terms of the COPYING file.
17
17
 *
18
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
19
 * KIND, either express or implied.
20
20
 *
21
 
 * $Id: file.c,v 1.22 2001/10/11 09:32:19 bumblebury Exp $
22
 
 *****************************************************************************/
 
21
 * $Id: file.c,v 1.53 2004/04/06 15:14:10 bagder Exp $
 
22
 ***************************************************************************/
23
23
 
24
24
#include "setup.h"
25
25
 
 
26
#ifndef CURL_DISABLE_FILE
26
27
/* -- WIN32 approved -- */
27
28
#include <stdio.h>
28
29
#include <string.h>
35
36
#include <errno.h>
36
37
 
37
38
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
38
 
#include <winsock.h>
39
39
#include <time.h>
40
40
#include <io.h>
41
41
#include <fcntl.h>
47
47
#include <netinet/in.h>
48
48
#endif
49
49
#include <sys/time.h>
50
 
#include <sys/resource.h>
51
50
#ifdef HAVE_UNISTD_H
52
51
#include <unistd.h>
53
52
#endif
82
81
#include "progress.h"
83
82
#include "sendf.h"
84
83
#include "escape.h"
 
84
#include "file.h"
 
85
#include "speedcheck.h"
 
86
#include "getinfo.h"
 
87
#include "transfer.h" /* for Curl_readwrite_init() */
85
88
 
86
89
#define _MPRINTF_REPLACE /* use our functions only */
87
90
#include <curl/mprintf.h>
88
91
 
89
92
/* The last #include file should be: */
90
 
#ifdef MALLOCDEBUG
 
93
#ifdef CURLDEBUG
91
94
#include "memdebug.h"
92
95
#endif
93
96
 
94
97
/* Emulate a connect-then-transfer protocol. We connect to the file here */
95
98
CURLcode Curl_file_connect(struct connectdata *conn)
96
99
{
97
 
  char *actual_path = curl_unescape(conn->path, 0);
98
 
  struct FILE *file;
 
100
  char *real_path = curl_unescape(conn->path, 0);
 
101
  struct FILEPROTO *file;
99
102
  int fd;
100
103
#if defined(WIN32) || defined(__EMX__)
101
104
  int i;
 
105
  char *actual_path;
102
106
#endif
103
107
 
104
 
  file = (struct FILE *)malloc(sizeof(struct FILE));
 
108
  file = (struct FILEPROTO *)calloc(sizeof(struct FILEPROTO), 1);
105
109
  if(!file)
106
110
    return CURLE_OUT_OF_MEMORY;
107
111
 
108
 
  memset(file, 0, sizeof(struct FILE));
109
112
  conn->proto.file = file;
110
113
 
111
114
#if defined(WIN32) || defined(__EMX__)
 
115
  /* If the first character is a slash, and there's
 
116
     something that looks like a drive at the beginning of
 
117
     the path, skip the slash.  If we remove the initial
 
118
     slash in all cases, paths without drive letters end up
 
119
     relative to the current directory which isn't how
 
120
     browsers work.
 
121
 
 
122
     Some browsers accept | instead of : as the drive letter
 
123
     separator, so we do too.
 
124
 
 
125
     On other platforms, we need the slash to indicate an
 
126
     absolute pathname.  On Windows, absolute paths start
 
127
     with a drive letter.
 
128
  */
 
129
  actual_path = real_path;
 
130
  if ((actual_path[0] == '/') &&
 
131
      actual_path[1] &&
 
132
      (actual_path[2] == ':' || actual_path[2] == '|'))
 
133
  {
 
134
    actual_path[2] = ':';
 
135
    actual_path++;
 
136
  }
 
137
 
112
138
  /* change path separators from '/' to '\\' for Windows and OS/2 */
113
139
  for (i=0; actual_path[i] != '\0'; ++i)
114
140
    if (actual_path[i] == '/')
116
142
 
117
143
  fd = open(actual_path, O_RDONLY | O_BINARY);  /* no CR/LF translation! */
118
144
#else
119
 
  fd = open(actual_path, O_RDONLY);
 
145
  fd = open(real_path, O_RDONLY);
120
146
#endif
121
 
  free(actual_path);
 
147
  free(real_path);
122
148
 
123
149
  if(fd == -1) {
124
150
    failf(conn->data, "Couldn't open file %s", conn->path);
129
155
  return CURLE_OK;
130
156
}
131
157
 
 
158
#if defined(WIN32) && (SIZEOF_CURL_OFF_T > 4)
 
159
#define lseek(x,y,z) _lseeki64(x, y, z)
 
160
#endif
 
161
 
132
162
/* This is the do-phase, separated from the connect-phase above */
133
163
 
134
164
CURLcode Curl_file(struct connectdata *conn)
140
170
  */
141
171
  CURLcode res = CURLE_OK;
142
172
  struct stat statbuf;
143
 
  ssize_t expected_size=-1;
 
173
  curl_off_t expected_size=0;
 
174
  bool fstated=FALSE;
144
175
  ssize_t nread;
145
176
  struct SessionHandle *data = conn->data;
146
177
  char *buf = data->state.buffer;
147
 
  int bytecount = 0;
148
 
  struct timeval start = Curl_tvnow();
149
 
  struct timeval now = start;
 
178
  curl_off_t bytecount = 0;
150
179
  int fd;
 
180
  struct timeval now = Curl_tvnow();
 
181
 
 
182
  Curl_readwrite_init(conn);
 
183
  Curl_initinfo(data);
 
184
  Curl_pgrsStartNow(data);
151
185
 
152
186
  /* get the fd from the connection phase */
153
187
  fd = conn->proto.file->fd;
154
188
 
155
 
/*VMS?? -- This only works reliable for STREAMLF files */
 
189
  /* VMS: This only works reliable for STREAMLF files */
156
190
  if( -1 != fstat(fd, &statbuf)) {
157
191
    /* we could stat it, then read out the size */
158
192
    expected_size = statbuf.st_size;
159
 
  }
 
193
    fstated = TRUE;
 
194
  }
 
195
 
 
196
  /* If we have selected NOBODY and HEADER, it means that we only want file
 
197
     information. Which for FILE can't be much more than the file size and
 
198
     date. */
 
199
  if(conn->bits.no_body && data->set.include_header && fstated) {
 
200
    CURLcode result;
 
201
    sprintf(buf, "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
 
202
    result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
 
203
    if(result)
 
204
      return result;
 
205
 
 
206
    sprintf(buf, "Accept-ranges: bytes\r\n");
 
207
    result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
 
208
    if(result)
 
209
      return result;
 
210
 
 
211
#ifdef HAVE_STRFTIME
 
212
    if(fstated) {
 
213
      struct tm *tm;
 
214
      time_t clock = (time_t)statbuf.st_mtime;
 
215
#ifdef HAVE_GMTIME_R
 
216
      struct tm buffer;
 
217
      tm = (struct tm *)gmtime_r(&clock, &buffer);
 
218
#else
 
219
      tm = gmtime(&clock);
 
220
#endif
 
221
      /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
 
222
      strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n",
 
223
               tm);
 
224
      result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
 
225
    }
 
226
#endif
 
227
    return result;
 
228
  }
 
229
 
 
230
  /* Added by Dolbneff A.V & Spiridonoff A.V */
 
231
  if (conn->resume_from <= expected_size)
 
232
    expected_size -= conn->resume_from;
 
233
  else
 
234
    /* Is this error code suitable in such situation? */
 
235
    return CURLE_FTP_BAD_DOWNLOAD_RESUME;
 
236
 
 
237
  if (fstated && (expected_size == 0))
 
238
    return CURLE_OK;
160
239
 
161
240
  /* The following is a shortcut implementation of file reading
162
241
     this is both more efficient than the former call to download() and
163
242
     it avoids problems with select() and recv() on file descriptors
164
243
     in Winsock */
165
 
  if(expected_size != -1)
 
244
  if(fstated)
166
245
    Curl_pgrsSetDownloadSize(data, expected_size);
167
246
 
 
247
  if(conn->resume_from)
 
248
    lseek(fd, conn->resume_from, SEEK_SET);
 
249
 
 
250
  Curl_pgrsTime(data, TIMER_STARTTRANSFER);
 
251
 
168
252
  while (res == CURLE_OK) {
169
253
    nread = read(fd, buf, BUFSIZE-1);
170
254
 
184
268
    if(res)
185
269
      return res;
186
270
 
187
 
    now = Curl_tvnow();
 
271
    Curl_pgrsSetDownloadCounter(data, bytecount);
 
272
 
188
273
    if(Curl_pgrsUpdate(conn))
189
274
      res = CURLE_ABORTED_BY_CALLBACK;
 
275
    else
 
276
      res = Curl_speedcheck (data, now);
190
277
  }
191
 
  now = Curl_tvnow();
192
278
  if(Curl_pgrsUpdate(conn))
193
279
    res = CURLE_ABORTED_BY_CALLBACK;
194
280
 
196
282
 
197
283
  return res;
198
284
}
199
 
 
200
 
/*
201
 
 * local variables:
202
 
 * eval: (load-file "../curl-mode.el")
203
 
 * end:
204
 
 * vim600: fdm=marker
205
 
 * vim: et sw=2 ts=2 sts=2 tw=78
206
 
 */
 
285
#endif