+ if (setjmp(urgcatch)) {
+ transflag = 0;
+ return;
+ }
+ while (dirname = *dirlist++) {
+ if (stat(dirname, &st) < 0) {
+ /*
+ * If user typed "ls -l", etc, and the client
+ * used NLST, do what the user meant.
+ */
+ if (dirname[0] == '-' && *dirlist == NULL &&
+ transflag == 0) {
+ retrieve("/bin/ls %s", dirname);
+ return;
+ }
+ perror_reply(550, whichfiles);
+ if (dout != NULL) {
+ (void) fclose(dout);
+ transflag = 0;
+ data = -1;
+ pdata = -1;
+ }
+ return;
+ }
+
+ if ((st.st_mode&S_IFMT) == S_IFREG) {
+ if (dout == NULL) {
+ dout = dataconn("file list", (off_t)-1, "w");
+ if (dout == NULL)
+ return;
+ transflag++;
+ }
+ fprintf(dout, "%s%s\n", dirname,
+ type == TYPE_A ? "\r" : "");
+ byte_count += strlen(dirname) + 1;
+ continue;
+ } else if ((st.st_mode&S_IFMT) != S_IFDIR)
+ continue;
+
+ if ((dirp = opendir(dirname)) == NULL)
+ continue;
+
+ while ((dir = readdir(dirp)) != NULL) {
+ char nbuf[MAXPATHLEN];
+
+ if (dir->d_name[0] == '.' && dir->d_namlen == 1)
+ continue;
+ if (dir->d_name[0] == '.' && dir->d_name[1] == '.' &&
+ dir->d_namlen == 2)
+ continue;
+
+ sprintf(nbuf, "%s/%s", dirname, dir->d_name);
+
+ /*
+ * We have to do a stat to insure it's
+ * not a directory or special file.
+ */
+ if (simple || (stat(nbuf, &st) == 0 &&
+ (st.st_mode&S_IFMT) == S_IFREG)) {
+ if (dout == NULL) {
+ dout = dataconn("file list", (off_t)-1,
+ "w");
+ if (dout == NULL)
+ return;
+ transflag++;
+ }
+ if (nbuf[0] == '.' && nbuf[1] == '/')
+ fprintf(dout, "%s%s\n", &nbuf[2],
+ type == TYPE_A ? "\r" : "");
+ else
+ fprintf(dout, "%s%s\n", nbuf,
+ type == TYPE_A ? "\r" : "");
+ byte_count += strlen(nbuf) + 1;
+ }
+ }
+ (void) closedir(dirp);
+ }
+
+ if (dout == NULL)
+ reply(550, "No files found.");
+ else if (ferror(dout) != 0)
+ perror_reply(550, "Data connection");