- int r, len;
- FILE *fp;
- char *cmd;
- char buf[GUESTFS_MAX_CHUNK_SIZE];
-
- NEED_ROOT (-1);
- ABS_PATH (dir, -1);
-
- /* "tar -C /sysroot%s -cf - ." but we have to quote the dir. */
- len = 2 * strlen (dir) + 32;
- cmd = malloc (len);
- if (!cmd) {
- reply_with_perror ("malloc");
- return -1;
- }
- strcpy (cmd, "tar -C /sysroot");
- shell_quote (cmd+15, len-15, dir);
- strcat (cmd, " -cf - .");
-
- fp = popen (cmd, "r");
- if (fp == NULL) {
- reply_with_perror ("%s", cmd);
- return -1;
- }
-
- /* Now we must send the reply message, before the file contents. After
- * this there is no opportunity in the protocol to send any error
- * message back. Instead we can only cancel the transfer.
- */
- reply (NULL, NULL);
-
- while ((r = fread (buf, 1, sizeof buf, fp)) > 0) {
- if (send_file_write (buf, r) < 0) {
- pclose (fp);
- return -1;
- }
- }
-
- if (ferror (fp)) {
- perror (dir);
- send_file_end (1); /* Cancel. */
- pclose (fp);
- return -1;
- }
-
- if (pclose (fp) == -1) {
- perror (dir);
- send_file_end (1); /* Cancel. */
- return -1;
- }
-
- send_file_end (0); /* Normal end of file. */
- return 0;