new
[libcurl.git] / lib / file.c
blob6e1dadf035c395d01f1735d454cea54414c47205
1 /*****************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * The contents of this file are subject to the Mozilla Public License
9 * Version 1.0 (the "License"); you may not use this file except in
10 * compliance with the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
13 * Software distributed under the License is distributed on an "AS IS"
14 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
15 * License for the specific language governing rights and limitations
16 * under the License.
18 * The Original Code is Curl.
20 * The Initial Developer of the Original Code is Daniel Stenberg.
22 * Portions created by the Initial Developer are Copyright (C) 1999.
23 * All Rights Reserved.
25 * ------------------------------------------------------------
26 * Main author:
27 * - Daniel Stenberg <Daniel.Stenberg@haxx.nu>
29 * http://curl.haxx.nu
31 * $Source: /cvsroot/curl/curl/lib/file.c,v $
32 * $Revision: 1.1.1.1 $
33 * $Date: 1999-12-29 14:21:21 $
34 * $Author: bagder $
35 * $State: Exp $
36 * $Locker: $
38 * ------------------------------------------------------------
39 ****************************************************************************/
41 /* -- WIN32 approved -- */
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdarg.h>
45 #include <stdlib.h>
46 #include <ctype.h>
47 #include <sys/types.h>
48 #include <sys/stat.h>
50 #include <errno.h>
52 #include "setup.h"
54 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
55 #include <winsock.h>
56 #include <time.h>
57 #include <io.h>
58 #include <fcntl.h>
59 #else
60 #ifdef HAVE_SYS_SOCKET_H
61 #include <sys/socket.h>
62 #endif
63 #include <netinet/in.h>
64 #include <sys/time.h>
65 #include <sys/resource.h>
66 #ifdef HAVE_UNISTD_H
67 #include <unistd.h>
68 #endif
69 #include <netdb.h>
70 #ifdef HAVE_ARPA_INET_H
71 #include <arpa/inet.h>
72 #endif
73 #ifdef HAVE_NET_IF_H
74 #include <net/if.h>
75 #endif
76 #include <sys/ioctl.h>
77 #include <signal.h>
79 #ifdef HAVE_SYS_PARAM_H
80 #include <sys/param.h>
81 #endif
83 #ifdef HAVE_SYS_STAT_H
84 #include <sys/stat.h>
85 #endif
86 #ifdef HAVE_FCNTL_H
87 #include <fcntl.h>
88 #endif
91 #endif
93 #include "urldata.h"
94 #include <curl/curl.h>
95 #include "progress.h"
96 #include "sendf.h"
97 #include "escape.h"
99 #define _MPRINTF_REPLACE /* use our functions only */
100 #include <curl/mprintf.h>
103 UrgError file(struct UrlData *data, char *path, long *bytecountp)
105 /* This implementation ignores the host name in conformance with
106 RFC 1738. Only local files (reachable via the standard file system)
107 are supported. This means that files on remotely mounted directories
108 (via NFS, Samba, NT sharing) can be accessed through a file:// URL
111 struct stat statbuf;
112 size_t expected_size=-1;
113 size_t nread;
114 char *buf = data->buffer;
115 int bytecount = 0;
116 struct timeval start = tvnow();
117 struct timeval now = start;
118 int fd;
119 char *actual_path = curl_unescape(path);
121 #ifdef WIN32
122 int i;
124 /* change path separators from '/' to '\\' for Windows */
125 for (i=0; actual_path[i] != '\0'; ++i)
126 if (actual_path[i] == '/')
127 actual_path[i] = '\\';
129 fd = open(actual_path, O_RDONLY | O_BINARY); /* no CR/LF translation! */
130 #else
131 fd = open(actual_path, O_RDONLY);
132 #endif
133 free(actual_path);
135 if(fd == -1) {
136 failf(data, "Couldn't open file %s", path);
137 return URG_FILE_COULDNT_READ_FILE;
139 if( -1 != fstat(fd, &statbuf)) {
140 /* we could stat it, then read out the size */
141 expected_size = statbuf.st_size;
144 /* The following is a shortcut implementation of file reading
145 this is both more efficient than the former call to download() and
146 it avoids problems with select() and recv() on file descriptors
147 in Winsock */
148 ProgressInit (data, expected_size);
149 while (1) {
150 nread = read(fd, buf, BUFSIZE-1);
152 if (0 <= nread)
153 buf[nread] = 0;
155 if (nread <= 0)
156 break;
157 bytecount += nread;
158 /* NOTE: The following call to fwrite does CR/LF translation on
159 Windows systems if the target is stdout. Use -O or -o parameters
160 to prevent CR/LF translation (this then goes to a binary mode
161 file descriptor). */
162 if(nread != data->fwrite (buf, 1, nread, data->out)) {
163 failf (data, "Failed writing output");
164 return URG_WRITE_ERROR;
166 now = tvnow();
167 ProgressShow (data, bytecount, start, now, FALSE);
169 now = tvnow();
170 ProgressShow (data, bytecount, start, now, TRUE);
172 close(fd);
174 return URG_OK;