+
+ /*
+ * Otherwise, the fun begins. We must fxp_opendir() the
+ * directory, slurp the filenames into memory, return
+ * SCP_SINK_DIR, and set targetisdir. The next time
+ * we're called, we will run through the list of
+ * filenames one by one.
+ *
+ * If targetisdir is _already_ set (meaning we're
+ * already in the middle of going through another such
+ * list), we must push the other (target,namelist) pair
+ * on a stack.
+ */
+ dirhandle = fxp_opendir(fname);
+ if (!dirhandle) {
+ tell_user(stderr, "scp: unable to open directory %s: %s",
+ fname, fxp_error());
+ if (must_free_fname) sfree(fname);
+ errs++;
+ return 1;
+ }
+ nnames = namesize = 0;
+ ournames = NULL;
+ while (1) {
+ int i;
+
+ names = fxp_readdir(dirhandle);
+ if (names == NULL) {
+ if (fxp_error_type() == SSH_FX_EOF)
+ break;
+ tell_user(stderr, "scp: reading directory %s: %s\n",
+ fname, fxp_error());
+ if (must_free_fname) sfree(fname);
+ sfree(ournames);
+ errs++;
+ return 1;
+ }
+ if (names->nnames == 0) {
+ fxp_free_names(names);
+ break;
+ }
+ if (nnames + names->nnames >= namesize) {
+ namesize += names->nnames + 128;
+ ournames =
+ srealloc(ournames, namesize * sizeof(*ournames));
+ }
+ for (i = 0; i < names->nnames; i++)
+ ournames[nnames++] = names->names[i];
+ names->nnames = 0; /* prevent free_names */
+ fxp_free_names(names);
+ }
+ fxp_close(dirhandle);
+
+ newitem = smalloc(sizeof(struct scp_sftp_dirstack));
+ newitem->next = scp_sftp_dirstack_head;
+ newitem->names = ournames;
+ newitem->namepos = 0;
+ newitem->namelen = nnames;
+ if (must_free_fname)
+ newitem->dirpath = fname;
+ else
+ newitem->dirpath = dupstr(fname);
+ scp_sftp_dirstack_head = newitem;
+
+ act->action = SCP_SINK_DIR;
+ act->buf = dupstr(stripslashes(fname));
+ act->name = act->buf;
+ act->size = 0; /* duhh, it's a directory */
+ act->mode = 07777 & attrs.permissions;
+ if (scp_sftp_preserve &&
+ (attrs.flags & SSH_FILEXFER_ATTR_ACMODTIME)) {
+ act->atime = attrs.atime;
+ act->mtime = attrs.mtime;
+ act->settime = 1;
+ } else
+ act->settime = 0;