Skip to content

file:// : Allow getting basic directory listings - #13137

Closed
colinleroy wants to merge 1 commit into
curl:masterfrom
colinleroy:add-file-protocol-list
Closed

file:// : Allow getting basic directory listings#13137
colinleroy wants to merge 1 commit into
curl:masterfrom
colinleroy:add-file-protocol-list

Conversation

@colinleroy

Copy link
Copy Markdown
Contributor

Hi Daniel & curl team,

Here's a little PR that allows one to get basic directory listings over file://, like for example:

$ ./src/curl file:///home/colin/Documents/git-oss/curl/
winbuild
configure~
autom4te.cache
MacOSX-Framework
LICENSES
CMake
libtool
config.status
libcurl.pc.in
missing
...

I hope you folks will consider it useful. For me, it's a way to start diving into curl code to implement the same for smb:// (which, of course, seems to be much more complicated).

@gvanem

gvanem commented Mar 16, 2024

Copy link
Copy Markdown
Contributor

Useful IMHO, but not all targets have readdir() etc.
So consider adding MSVC-support for this <dirent.h> stuff from e.g.
https://github.com/ThomasDickey/lynx-snapshots/blob/master/lib/dirent.h

into this PR first.

@colinleroy

colinleroy commented Mar 16, 2024

Copy link
Copy Markdown
Contributor Author

Useful IMHO, but not all targets have readdir() etc. So consider adding MSVC-support for this <dirent.h> stuff from e.g. https://github.com/ThomasDickey/lynx-snapshots/blob/master/lib/dirent.h

into this PR first.

Thank you for your comment, I'll do that. The linters are being mean to me, I'll handle that too.
Edit: Would you have some pointers about how to do that (like maybe another example of thing added for MSVC)?

I don't have a Windows development machine, VM or setup so I feel there may be a few issues I'll have to sort through.

@dfandrich

dfandrich commented Mar 16, 2024

Copy link
Copy Markdown
Contributor

Be sure to take a look at PR #9746 and its comments.

@bagder

bagder commented Mar 16, 2024

Copy link
Copy Markdown
Member

The linters are being mean to me

make checksrc locally is a good idea...

Comment thread lib/file.c Outdated
*data = NULL;
*size = 0;

if(!file) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can file actually and legitimately be NULL here? Shouldn't this rather be an assert since it should never happen in real life?

Comment thread lib/file.c Outdated

dir = fdopendir(file->fd);
if(!dir) {
result = CURLE_BAD_FUNCTION_ARGUMENT;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error is curious, since it already opened the file and it is said to be a dir, but this still fails. It seems to me that CURLE_BAD_FUNCTION_ARGUMENT is not the most accurate description of this error. Maybe just CURLE_READ_ERROR ?

Comment thread lib/file.c Outdated

*data = tmp;
snprintf(*data + *size, entry_len + 1, "%s\n", entry->d_name);
*size += entry_len;

@bagder bagder Mar 16, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it not make sense to just pass on the file entry to the write callback as soon as you have it, rather than to create a (potentially huge) allocated buffer and send them all later?

And if you do prefer the buffer approach, please use a dynbuf to avoid manual reallocs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with a temporary buffer because it seemed much easier to calculate expected_size and do resuming. Do you think that's a good enough reason to go the buffer route?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does provide an expected size, that is true. But resuming sounds super fragile and will break horribly if something in the directory changes in between...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm this is true. Is it acceptable to reject resumes in case of a directory listing?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's the only sensible thing to do

@colinleroy

Copy link
Copy Markdown
Contributor Author

I repushed to address your comments. Is this something like that you had in mind?

@colinleroy
colinleroy force-pushed the add-file-protocol-list branch from 26ea08f to e457ebc Compare March 18, 2024 16:55
Comment thread lib/file.c Outdated
goto out;
}
else {
DIR *dir = fdopendir(file->fd);

@bagder bagder Mar 19, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to add a check for fdopendir() to configure and CMake so that we know it exists for the platform you build this for. On Windows it won't exist. For now at least, I think we can presume the other POSIX dir funtions exist if this one does.

Then you can either opt to fail on other platforms, or continue to add support other dir-reading functions. Windows being a primary target I guess.

macOS also needs attention as the compiler there says:

'fdopendir' has been marked as being introduced in macOS 10.10 here, but the deployment target is macOS 10.9.0

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @bagder,
Thanks for your feedback. I will add the configure/CMake checks this evening, and probably switch to opendir(file->path) to address the Mac OS X case.
For Windows, I'll see if I can find someone with Windows experience to help me either add wrappers or #ifdefs.

@bagder

bagder commented Mar 19, 2024

Copy link
Copy Markdown
Member

I googled the Windows API for this and it seems fairly simple. Something in this style lists the contents of a given directory:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

void listdir(const char *dir)
{
    WIN32_FIND_DATA entry;
    HANDLE h;
    char *wc = aprintf("%s\\*.*", dir);
    if(!wc)
      return; /* out of mem */

    h = FindFirstFile(wc, &entry);
    if(h == INVALID_HANDLE_VALUE)
      return;

    do {
      printf("%s\n", entry.cFileName);
    } while(FindNextFile(h, &entry));

    FindClose(h);
    free(wc);
}

Rough example, but the function calls should show.

@colinleroy

Copy link
Copy Markdown
Contributor Author

I'm unsure the two failing pipelines are failed related to the PR?

@colinleroy

Copy link
Copy Markdown
Contributor Author

Concerning Windows, is it OK if I do it in a different PR?

@bagder

bagder commented Mar 21, 2024

Copy link
Copy Markdown
Member

Concerning Windows, is it OK if I do it in a different PR?

Absolutely. As long as this PR does not break their builds or misbehaves for them in other ways.

@bagder bagder left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: I deem this to be a "feature/change", which means that we will not merge this PR until the feature window opens again. (Normally 10 days after a release.)

Comment thread lib/file.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the #ifdef (and #else, and #endif) to column zero.

Comment thread lib/file.c Outdated
Comment thread lib/urldata.h Outdated
@bagder bagder added the feature-window A merge of this requires an open feature window label Mar 21, 2024
@colinleroy

Copy link
Copy Markdown
Contributor Author

FYI: I deem this to be a "feature/change", which means that we will not merge this PR until the feature window opens again. (Normally 10 days after a release.)

That seems logical :)
Your latest comments should be addressed in the last push.

@github-actions github-actions Bot added the tests label Mar 22, 2024
@colinleroy
colinleroy force-pushed the add-file-protocol-list branch from 783a505 to 9ae94c6 Compare March 22, 2024 07:29
@colinleroy
colinleroy force-pushed the add-file-protocol-list branch from 9ae94c6 to 89fdcd3 Compare April 4, 2024 08:33
@colinleroy

Copy link
Copy Markdown
Contributor Author

Hi @bagder! I think the feature freeze is over?
do I have to do something about the failed Mac pipelines? It seems like they're unrelated to the PR?
Thanks 🙂

@bagder

bagder commented Apr 9, 2024

Copy link
Copy Markdown
Member

The freeze is over. Those CI fails should be fixed if you rebase and force-push.

I do miss a test case specifically for this feature.

@colinleroy
colinleroy force-pushed the add-file-protocol-list branch from 89fdcd3 to dea3e21 Compare April 10, 2024 08:44
@colinleroy

Copy link
Copy Markdown
Contributor Author

Hi Daniel,
PR rebased, test added (i hope it's what you expected?) and CI passed!

@bagder bagder left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@bagder bagder closed this in bfe54b0 Apr 11, 2024
@bagder

bagder commented Apr 11, 2024

Copy link
Copy Markdown
Member

Thanks!

vszakats added a commit that referenced this pull request Aug 26, 2024
- configure: disable pthreads by default on Windows.
- configure: disable detecting `fseeko()` on Windows.
  (It exists in mingw-w64 2.0.0 and newer, but it's permanently ignored
  in CMake, as this function is never necessary on Windows.)
- extend existing exceptions with their Windows variants.
- `lib/formdata.c`: prioritize `_fseeki64()` over `fseeko()`.
  To reduce the difference between Windows builds, which now all use
  `_fseeki64()`.
- cmake: perm-enable `HAVE_DIRENT_H` and `HAVE_OPENDIR` for mingw-w64,
  to match configure.
  Follow-up to bfe54b0 #13137
  This in theory could make the dir listing feature work in mingw-w64
  build, but in my tests (on WINE) it failed at the preceding `open()`
  call.
- cmake: perm-enable `HAVE_STRINGS_H` and `HAVE_UTIME_H` for mingw-w64,
  to match configure. (They are wrappers and make no difference in the build.)

Also:
- configure: sync `USE_MANUAL` macro with cmake, by only setting it for
  `src`. Drop checker exception.
- CI: use `--disable-dependency-tracking` in existing jobs.
- CI: install packages before git checkout, in existing jobs.

Closes #14678
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cmdline tool feature-window A merge of this requires an open feature window tests

Development

Successfully merging this pull request may close these issues.

4 participants