1 /* libguestfs - the guestfsd daemon
2 * Copyright (C) 2009 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "../src/guestfs_protocol.h"
32 program_of_csum (const char *csumtype)
34 if (STRCASEEQ (csumtype, "crc"))
36 else if (STRCASEEQ (csumtype, "md5"))
38 else if (STRCASEEQ (csumtype, "sha1"))
40 else if (STRCASEEQ (csumtype, "sha224"))
42 else if (STRCASEEQ (csumtype, "sha256"))
44 else if (STRCASEEQ (csumtype, "sha384"))
46 else if (STRCASEEQ (csumtype, "sha512"))
49 reply_with_error ("unknown checksum type, expecting crc|md5|sha1|sha224|sha256|sha384|sha512");
55 checksum (const char *csumtype, const char *path)
62 program = program_of_csum (csumtype);
66 r = command (&out, &err, program, path, NULL);
68 reply_with_error ("%s: %s", program, err);
76 /* Split it at the first whitespace. */
77 len = strcspn (out, " \t\n");
80 return out; /* Caller frees. */
84 do_checksum (const char *csumtype, const char *path)
86 /* Make the path relative to /sysroot. */
87 char *buf = sysroot_path (path);
89 reply_with_perror ("malloc");
93 char *r = checksum (csumtype, buf);
99 do_checksum_device (const char *csumtype, const char *device)
101 return checksum (csumtype, device);
104 /* Has one FileOut parameter. */
106 do_checksums_out (const char *csumtype, const char *dir)
111 const char *program = program_of_csum (csumtype);
115 char *sysrootdir = sysroot_path (dir);
117 reply_with_perror ("malloc");
121 r = stat (sysrootdir, &statbuf);
123 reply_with_perror ("%s", dir);
127 if (!S_ISDIR (statbuf.st_mode)) {
128 reply_with_error ("%s: not a directory", dir);
134 if (asprintf_nowarn (&cmd, "cd %Q && find -type f -print0 | xargs -0 %s",
135 sysrootdir, program) == -1) {
136 reply_with_perror ("asprintf");
143 fprintf (stderr, "%s\n", cmd);
145 FILE *fp = popen (cmd, "r");
147 reply_with_perror ("%s", cmd);
153 /* Now we must send the reply message, before the file contents. After
154 * this there is no opportunity in the protocol to send any error
155 * message back. Instead we can only cancel the transfer.
159 char str[GUESTFS_MAX_CHUNK_SIZE];
161 while ((r = fread (str, 1, GUESTFS_MAX_CHUNK_SIZE, fp)) > 0) {
162 if (send_file_write (str, r) < 0) {
170 send_file_end (1); /* Cancel. */
175 if (pclose (fp) != 0) {
177 send_file_end (1); /* Cancel. */
181 if (send_file_end (0)) /* Normal end of file. */