set(HAVE_TERMIO_H 0)
set(HAVE_UTIME_H 0) # mingw-w64 has it (wrapper to sys/utime.h)
+set(HAVE_DIRENT_H 0)
+set(HAVE_OPENDIR 0)
+
set(HAVE_FSEEKO 0)
set(HAVE__FSEEKI64 1)
set(HAVE_SOCKET 1)
check_include_file_concat("sys/utime.h" HAVE_SYS_UTIME_H)
check_include_file_concat("sys/xattr.h" HAVE_SYS_XATTR_H)
check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H)
+check_include_file_concat("dirent.h" HAVE_DIRENT_H)
check_include_file_concat("fcntl.h" HAVE_FCNTL_H)
check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H)
check_include_file_concat("io.h" HAVE_IO_H)
check_symbol_exists(fnmatch "${CURL_INCLUDES};fnmatch.h" HAVE_FNMATCH)
check_symbol_exists(basename "${CURL_INCLUDES};string.h" HAVE_BASENAME)
+check_symbol_exists(opendir "${CURL_INCLUDES};dirent.h" HAVE_OPENDIR)
check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET)
check_symbol_exists(sched_yield "${CURL_INCLUDES};sched.h" HAVE_SCHED_YIELD)
check_symbol_exists(socketpair "${CURL_INCLUDES}" HAVE_SOCKETPAIR)
fi
fi
+AC_CHECK_HEADER(dirent.h,
+ [ AC_DEFINE(HAVE_DIRENT_H, 1, [if you have <dirent.h>])
+ AC_CHECK_FUNC(opendir, AC_DEFINE(HAVE_OPENDIR, 1, [if you have opendir]) )
+ ]
+)
+
CURL_CONVERT_INCLUDE_TO_ISYSTEM
dnl ************************************************************
SPDX-License-Identifier: curl
Long: list-only
Short: l
-Protocols: FTP POP3 SFTP
+Protocols: FTP POP3 SFTP FILE
Help: List only mode
Added: 4.0
-Category: ftp pop3 sftp
+Category: ftp pop3 sftp file
Multi: boolean
See-also:
- quote
to be performed instead of RETR. This is particularly useful if the user wants
to see if a specific message-id exists on the server and what size it is.
+For FILE, this option has no effect yet as directories are always listed in
+this mode.
+
Note: When combined with --request, this option can be used to send a UIDL
command instead, so the user may use the email's unique identifier rather than
its message-id to make the request.
of libcurl, when combined with a URL that contains a message ID, to perform a
"scan listing" which can then be used to determine the size of an email.
+For FILE, this option has no effect yet as directories are always listed in
+this mode.
+
Note: For FTP this causes a NLST command to be sent to the FTP server. Beware
that some FTP servers list only files in their response to NLST; they might
not include subdirectories and symbolic links.
/* Define to 1 if you have the `closesocket' function. */
#cmakedefine HAVE_CLOSESOCKET 1
+/* Define to 1 if you have the <dirent.h> header file. */
+#cmakedefine HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the `opendir' function. */
+#cmakedefine HAVE_OPENDIR 1
+
/* Define to 1 if you have the fcntl function. */
#cmakedefine HAVE_FCNTL 1
#include <fcntl.h>
#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+
#include "strtoofft.h"
#include "urldata.h"
#include <curl/curl.h>
Curl_pgrsSetDownloadSize(data, expected_size);
if(data->state.resume_from) {
- if(data->state.resume_from !=
- lseek(fd, data->state.resume_from, SEEK_SET))
+ if(!S_ISDIR(statbuf.st_mode)) {
+ if(data->state.resume_from !=
+ lseek(fd, data->state.resume_from, SEEK_SET))
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+ else {
return CURLE_BAD_DOWNLOAD_RESUME;
+ }
}
result = Curl_multi_xfer_buf_borrow(data, &xfer_buf, &xfer_blen);
if(result)
goto out;
- while(!result) {
- ssize_t nread;
- /* Don't fill a whole buffer if we want less than all data */
- size_t bytestoread;
+ if(!S_ISDIR(statbuf.st_mode)) {
+ while(!result) {
+ ssize_t nread;
+ /* Don't fill a whole buffer if we want less than all data */
+ size_t bytestoread;
- if(size_known) {
- bytestoread = (expected_size < (curl_off_t)(xfer_blen-1)) ?
- curlx_sotouz(expected_size) : (xfer_blen-1);
- }
- else
- bytestoread = xfer_blen-1;
+ if(size_known) {
+ bytestoread = (expected_size < (curl_off_t)(xfer_blen-1)) ?
+ curlx_sotouz(expected_size) : (xfer_blen-1);
+ }
+ else
+ bytestoread = xfer_blen-1;
- nread = read(fd, xfer_buf, bytestoread);
+ nread = read(fd, xfer_buf, bytestoread);
- if(nread > 0)
- xfer_buf[nread] = 0;
+ if(nread > 0)
+ xfer_buf[nread] = 0;
- if(nread <= 0 || (size_known && (expected_size == 0)))
- break;
+ if(nread <= 0 || (size_known && (expected_size == 0)))
+ break;
- if(size_known)
- expected_size -= nread;
+ if(size_known)
+ expected_size -= nread;
- result = Curl_client_write(data, CLIENTWRITE_BODY, xfer_buf, nread);
- if(result)
- goto out;
+ result = Curl_client_write(data, CLIENTWRITE_BODY, xfer_buf, nread);
+ if(result)
+ goto out;
- if(Curl_pgrsUpdate(data))
- result = CURLE_ABORTED_BY_CALLBACK;
- else
- result = Curl_speedcheck(data, Curl_now());
- if(result)
+ if(Curl_pgrsUpdate(data))
+ result = CURLE_ABORTED_BY_CALLBACK;
+ else
+ result = Curl_speedcheck(data, Curl_now());
+ if(result)
+ goto out;
+ }
+ }
+ else {
+#ifdef HAVE_OPENDIR
+ DIR *dir = opendir(file->path);
+ struct dirent *entry;
+
+ if(!dir) {
+ result = CURLE_READ_ERROR;
goto out;
+ }
+ else {
+ while((entry = readdir(dir))) {
+ if(entry->d_name[0] != '.') {
+ result = Curl_client_write(data, CLIENTWRITE_BODY,
+ entry->d_name, strlen(entry->d_name));
+ if(result)
+ break;
+ result = Curl_client_write(data, CLIENTWRITE_BODY, "\n", 1);
+ if(result)
+ break;
+ }
+ }
+ closedir(dir);
+ }
+#else
+ failf(data, "Directory listing not yet implemented on this platform.");
+ result = CURLE_READ_ERROR;
+#endif
}
+
if(Curl_pgrsUpdate(data))
result = CURLE_ABORTED_BY_CALLBACK;
#define PROTO_FAMILY_SSH (CURLPROTO_SCP|CURLPROTO_SFTP)
#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) || \
- !defined(CURL_DISABLE_POP3)
+ !defined(CURL_DISABLE_POP3) || !defined(CURL_DISABLE_FILE)
/* these protocols support CURLOPT_DIRLISTONLY */
#define CURL_LIST_ONLY_PROTOCOL 1
#endif
CURLHELP_CONNECTION},
{"-l, --list-only",
"List only mode",
- CURLHELP_FTP | CURLHELP_POP3 | CURLHELP_SFTP},
+ CURLHELP_FTP | CURLHELP_POP3 | CURLHELP_SFTP | CURLHELP_FILE},
{" --local-port <range>",
"Use a local port number within RANGE",
CURLHELP_CONNECTION},
\
test3100 test3101 test3102 test3103 \
test3200 \
-test3201 test3202
+test3201 test3202 test3203
file: FILE protocol options
--create-file-mode <mode> File mode for created files
-I, --head Show document info only
+ -l, --list-only List only mode
-r, --range <range> Retrieve only the bytes within RANGE
</stdout>
</verify>
file: FILE protocol options
--create-file-mode <mode> File mode for created files
-I, --head Show document info only
+ -l, --list-only List only mode
-r, --range <range> Retrieve only the bytes within RANGE
</stdout>
</verify>
--- /dev/null
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+FILE
+</keywords>
+</info>
+
+#
+# Client-side
+<client>
+<server>
+file
+</server>
+<name>
+GET a directory using file://
+</name>
+<!-- doesn't work on win32, see #6379 -->
+<features>
+!win32
+</features>
+<command option="no-include">
+file://localhost%FILE_PWD/%LOGDIR/test%TESTNUMBER.dir/
+</command>
+<file name="%LOGDIR/test%TESTNUMBER.dir/dir-listing-test.txt">
+Contents of file are irrelevant
+</file>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+0
+</errorcode>
+<stdout>
+dir-listing-test.txt
+</stdout>
+</verify>
+</testcase>