
libcurl CURLOPT_DIRLISTONLY 选项完全指南FTP/SFTP 目录名列表与 POP3 扫描清单的实现原理与实战【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl导读CURLOPT_DIRLISTONLY是 libcurl 中用于控制仅列出名称行为的传输选项对 FTP/FTPS 与 SFTP 站点它把完整目录列表含大小、日期等元信息切换为只输出文件名的简洁清单对 POP3 服务器它则把默认的邮件正文下载改为扫描式清单从而可以在不下载正文的前提下获知邮件的存在性与大小。本文以 curl 官方文档 docs/libcurl/opts/CURLOPT_DIRLISTONLY.md 为主体骨架结合 lib/ftp.c、lib/pop3.c、lib/vssh/libssh2.c、lib/setopt.c 等源码实现完整讲解该选项的协议行为、内部调用链、命令行对应方式与常见注意事项。读完本文你将能够在 FTP、SFTP 与 POP3 场景下准确使用该选项并理解它为什么不能与CURLOPT_WILDCARDMATCH混用。选项概览功能定位CURLOPT_DIRLISTONLY的语义是只要名称列表ask for names only in a directory listing。它作用于三类协议协议开启后的行为FTP / FTPS向服务器发送NLST命令替代LIST仅返回文件名不包含大小、日期、权限等元信息SFTP在 SFTP 目录读取过程中只把每个条目的文件名写回给应用丢弃长格式属性long entryPOP3 / POP3S把默认的RETR取正文切换为LIST取消息清单可用于扫描邮件并得知其大小FILE无效果——file 协议下目录始终以名称列表方式列出从源码宏定义看该选项并非在所有构建中都可用只有启用了 FTP、SSHSFTP或 POP3 时才会定义CURL_LIST_ONLY_PROTOCOL进而注册该选项见 lib/protocol.h。默认值与可用版本默认值0关闭即完整列表模式见文档DEFAULT一节。加入版本7.17.0该选项最初以CURLOPT_FTPLISTONLY命名7.16.4 及更早版本使用旧名POP3 支持自 7.21.5 起加入。返回值curl_easy_setopt(3)返回CURLcodeCURLE_OK (0)表示成功非零表示出错具体错误码参见libcurl-errors(3)。签名#include curl/curl.h CURLcode curl_easy_setopt(CURL *handle, CURLOPT_DIRLISTONLY, long listonly);参数listonly传1L开启0L关闭。在 FTP / FTPS 中的应用从 LIST 到 NLST协议层面的切换对 FTP 来说开启该选项的直接后果是libcurl 向服务器发送NLST命令而非LIST。这一逻辑体现在 lib/ftp.c 的传输准备阶段result Curl_pp_sendf(data, ftpc-pp, PRET %s, CURL_EASY_STR(data, STRING_CUSTOMREQUEST) ? CURL_EASY_STR(data, STRING_CUSTOMREQUEST) : (data-state.list_only ? NLST : LIST));此处可见list_only标志直接决定了默认命令字串若同时设置了CURLOPT_CUSTOMREQUEST则自定义命令优先。类似的判定还出现在 FTP 状态机下发命令处lib/ftp.c以及目录条目解析分支lib/ftp.c共同保证了整个目录列举流程始终使用NLST。NLST与LIST的差异是关键LIST返回标准的长格式列表文件名、大小、日期、权限、属主等适合人类阅读与富信息解析NLST只返回名称清单一个名称一行数据量小、解析简单。注意文档明确指出部分 FTP 服务器对NLST的响应只包含普通文件可能不含子目录与符号链接。因此在依赖目录树遍历结果的场景下需要针对具体服务器行为做验证。目录尾斜杠不再是必要条件通常情况下libcurl 只有在 URL 路径以/结尾时才认为请求的是目录列举而开启CURLOPT_DIRLISTONLY后即使 URL 不以斜杠结尾也会被当作目录列举请求处理文档DESCRIPTION一节明确说明这一点。这在批量拼接 URL 时能减少对路径格式的依赖。结合 URL 中的 ;typeD 后缀从源码看FTP URL 支持;typecode后缀lib/ftp.c 的type_url_check()其中typeD会直接把data-state.list_only置为TRUEcase D: /* directory mode */ >#include curl/curl.h int main(void) { CURL *curl curl_easy_init(); if(curl) { CURLcode result; curl_easy_setopt(curl, CURLOPT_URL, ftp://example.com/dir/); /* 只取名称列表发送 NLST 而非 LIST */ curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1L); result curl_easy_perform(curl); if(result ! CURLE_OK) fprintf(stderr, curl_easy_perform() failed: %s\n, curl_easy_strerror(result)); curl_easy_cleanup(curl); } return 0; }运行后回调函数接收到的每一行即为目录中的单个名称通常以\n分隔。如需收集全部条目可在CURLOPT_WRITEFUNCTION回调中自行拼接缓冲。在 SFTP 中的应用丢弃长条目只留文件名底层行为对 SFTP 而言libcurl 通过 libssh2 的libssh2_sftp_readdir_ex读取目录条目会同时获得文件名与长格式属性串。开启CURLOPT_DIRLISTONLY后lib/vssh/libssh2.c 只把文件名写回给应用并补一个换行符if(data-set.list_only) { result Curl_client_write(data, CLIENTWRITE_BODY, sshp-readdir_filename, readdir_len); if(!result) result Curl_client_write(data, CLIENTWRITE_BODY, \n, 1); ... } else { /* 完整模式拼接长条目 */ result curlx_dyn_add(sshp-readdir, sshp-readdir_longentry); ... }libssh 后端lib/vssh/libssh.c也通过data-set.list_only做了同样的分支处理。因此无论使用哪个 SSH 后端开启该选项都能显著减小回传数据量适合只需文件名的自动化脚本。注意事项与 FTP 不同SFTP 的readdir本身就能拿到完整元数据list_only只是在客户端侧做了过滤不涉及额外的服务器命令。因此不存在 FTP 那种服务器可能漏报子目录的问题但同样地你拿到的也只是名称没有大小与类型信息。在 POP3 中的应用扫描清单scan listing默认行为 vs 扫描行为POP3 场景比较特殊。默认情况下当 URL 携带消息 ID 时例如pop3://userexample.com/1libcurl 会发送RETR 1下载该邮件的完整正文当 URL 不带消息 ID 时默认发送LIST获取全部消息清单。开启CURLOPT_DIRLISTONLY后lib/pop3.c 的pop3_perform_command()会把带消息 ID 的情况也切换为LIST/* Calculate the default command */ if(pop3-id[0] \0 ||># 仅列出 FTP 目录中的名称发送 NLST curl --list-only ftp://example.com/dir/ # 与 URL 后缀等价;typeD 也会触发仅名称模式 curl ftp://example.com/dir/;typeD # SFTP 场景下只取文件名 curl --list-only sftp://example.com/path/ # POP3 场景列出全部消息的编号与大小扫描清单 curl --list-only pop3://userexample.com/ # 指定消息 ID 时同样得到该消息的扫描信息而非正文 curl --list-only pop3://userexample.com/1注意--list-only也可配合--no-list-only显式关闭tool_getparam.c中所有ARG_BOOL参数都支持--no-前缀反转。选项在传输链路中的流转理解该选项的完整生命周期有助于排查问题。从源码可以梳理出如下调用链设置阶段curl_easy_setopt(handle, CURLOPT_DIRLISTONLY, 1L)进入 lib/setopt.c 的case CURLOPT_DIRLISTONLY把值写入data-set.list_only该字段定义于 lib/urldata.h 附近的 set 结构。请求初始化Curl_init_do()在 lib/transfer.c 把data-set.list_only复制到data-state.list_only运行态标志见 lib/urldata.h。协议处理FTP状态机在准备传输时依据data-state.list_only选择NLST还是LISTSFTP目录读取回调依据data-set.list_only决定输出文件名还是长条目POP3pop3_perform_command()依据data-set.list_only选择LIST还是RETR。可选注入FTP URL 的;typeD后缀会在type_url_check()中直接把运行态标志置位效果与步骤 1 相同。这种set 配置 state 运行态的双层设计使同一个连接句柄在重定向、连接复用等场景下都能保持一致的列举模式。典型使用场景小结批量抓取文件名在 FTP/SFTP 镜像站点上只拉取名称清单用于后续增量同步、监控新增文件降低列表传输开销大型目录的LIST响应可能很长NLST显著减少传输字节数POP3 邮件体检先LIST扫描消息编号与大小再决定是否RETR避免下载超大邮件正文与通配符匹配二选一需要ftp://.../dir/*.txt这类模式时使用CURLOPT_WILDCARDMATCH需要纯名称流时使用CURLOPT_DIRLISTONLY不要同时开启。参考文献本文主体官方选项文档 docs/libcurl/opts/CURLOPT_DIRLISTONLY.md选项注册与解析lib/setopt.c、lib/easyoptions.c含旧名FTPLISTONLY的别名映射协议可用性宏lib/protocol.hFTP 实现lib/ftp.cNLST/LIST选择与;typeD解析POP3 实现lib/pop3.cLIST/RETR选择SFTP 实现lib/vssh/libssh2.c 与 lib/vssh/libssh.c命令行对应-l, --list-only见 src/tool_getparam.c、src/tool_listhelp.c、src/config2setopts.c相关选项CURLOPT_CUSTOMREQUEST、CURLOPT_WILDCARDMATCH参见 docs/libcurl/opts/ 目录下对应文档【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考