fprintf (stderr, "warning: \"guestfs_scrub_freespace\" has no tests\n");
}
+static int test_tail_n_0_skip (void)
+{
+ const char *str;
+
+ str = getenv ("TEST_ONLY");
+ if (str)
+ return strstr (str, "tail_n") == NULL;
+ str = getenv ("SKIP_TEST_TAIL_N_0");
+ if (str && strcmp (str, "1") == 0) return 1;
+ str = getenv ("SKIP_TEST_TAIL_N");
+ if (str && strcmp (str, "1") == 0) return 1;
+ return 0;
+}
+
+static int test_tail_n_0 (void)
+{
+ if (test_tail_n_0_skip ()) {
+ printf ("%s skipped (reason: environment variable set)\n", "test_tail_n_0");
+ return 0;
+ }
+
+ /* InitBasicFS for test_tail_n_0: create ext2 on /dev/sda1 */
+ {
+ char device[] = "/dev/sda";
+ int r;
+ suppress_error = 0;
+ r = guestfs_blockdev_setrw (g, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda";
+ char lines_0[] = ",";
+ char *lines[] = {
+ lines_0,
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, device, 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char fstype[] = "ext2";
+ char device[] = "/dev/sda1";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, fstype, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda1";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for tail_n (0) */
+ {
+ char options[] = "ro";
+ char vfstype[] = "squashfs";
+ char device[] = "/dev/sdd";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount_vfs (g, options, vfstype, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char path[] = "/10klines";
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_tail_n (g, 3, path);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_tail_n_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9997abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[0], expected) != 0) {
+ fprintf (stderr, "test_tail_n_0: expected \"%s\" but got \"%s\"\n", expected, r[0]);
+ return -1;
+ }
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_tail_n_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9998abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[1], expected) != 0) {
+ fprintf (stderr, "test_tail_n_0: expected \"%s\" but got \"%s\"\n", expected, r[1]);
+ return -1;
+ }
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_tail_n_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9999abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[2], expected) != 0) {
+ fprintf (stderr, "test_tail_n_0: expected \"%s\" but got \"%s\"\n", expected, r[2]);
+ return -1;
+ }
+ }
+ if (r[3] != NULL) {
+ fprintf (stderr, "test_tail_n_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_tail_n_1_skip (void)
+{
+ const char *str;
+
+ str = getenv ("TEST_ONLY");
+ if (str)
+ return strstr (str, "tail_n") == NULL;
+ str = getenv ("SKIP_TEST_TAIL_N_1");
+ if (str && strcmp (str, "1") == 0) return 1;
+ str = getenv ("SKIP_TEST_TAIL_N");
+ if (str && strcmp (str, "1") == 0) return 1;
+ return 0;
+}
+
+static int test_tail_n_1 (void)
+{
+ if (test_tail_n_1_skip ()) {
+ printf ("%s skipped (reason: environment variable set)\n", "test_tail_n_1");
+ return 0;
+ }
+
+ /* InitBasicFS for test_tail_n_1: create ext2 on /dev/sda1 */
+ {
+ char device[] = "/dev/sda";
+ int r;
+ suppress_error = 0;
+ r = guestfs_blockdev_setrw (g, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda";
+ char lines_0[] = ",";
+ char *lines[] = {
+ lines_0,
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, device, 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char fstype[] = "ext2";
+ char device[] = "/dev/sda1";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, fstype, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda1";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for tail_n (1) */
+ {
+ char options[] = "ro";
+ char vfstype[] = "squashfs";
+ char device[] = "/dev/sdd";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount_vfs (g, options, vfstype, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char path[] = "/10klines";
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_tail_n (g, -9998, path);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_tail_n_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9997abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[0], expected) != 0) {
+ fprintf (stderr, "test_tail_n_1: expected \"%s\" but got \"%s\"\n", expected, r[0]);
+ return -1;
+ }
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_tail_n_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9998abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[1], expected) != 0) {
+ fprintf (stderr, "test_tail_n_1: expected \"%s\" but got \"%s\"\n", expected, r[1]);
+ return -1;
+ }
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_tail_n_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9999abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[2], expected) != 0) {
+ fprintf (stderr, "test_tail_n_1: expected \"%s\" but got \"%s\"\n", expected, r[2]);
+ return -1;
+ }
+ }
+ if (r[3] != NULL) {
+ fprintf (stderr, "test_tail_n_1: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_tail_n_2_skip (void)
+{
+ const char *str;
+
+ str = getenv ("TEST_ONLY");
+ if (str)
+ return strstr (str, "tail_n") == NULL;
+ str = getenv ("SKIP_TEST_TAIL_N_2");
+ if (str && strcmp (str, "1") == 0) return 1;
+ str = getenv ("SKIP_TEST_TAIL_N");
+ if (str && strcmp (str, "1") == 0) return 1;
+ return 0;
+}
+
+static int test_tail_n_2 (void)
+{
+ if (test_tail_n_2_skip ()) {
+ printf ("%s skipped (reason: environment variable set)\n", "test_tail_n_2");
+ return 0;
+ }
+
+ /* InitBasicFS for test_tail_n_2: create ext2 on /dev/sda1 */
+ {
+ char device[] = "/dev/sda";
+ int r;
+ suppress_error = 0;
+ r = guestfs_blockdev_setrw (g, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda";
+ char lines_0[] = ",";
+ char *lines[] = {
+ lines_0,
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, device, 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char fstype[] = "ext2";
+ char device[] = "/dev/sda1";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, fstype, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda1";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for tail_n (2) */
+ {
+ char options[] = "ro";
+ char vfstype[] = "squashfs";
+ char device[] = "/dev/sdd";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount_vfs (g, options, vfstype, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char path[] = "/10klines";
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_tail_n (g, 0, path);
+ if (r == NULL)
+ return -1;
+ if (r[0] != NULL) {
+ fprintf (stderr, "test_tail_n_2: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_tail_0_skip (void)
+{
+ const char *str;
+
+ str = getenv ("TEST_ONLY");
+ if (str)
+ return strstr (str, "tail") == NULL;
+ str = getenv ("SKIP_TEST_TAIL_0");
+ if (str && strcmp (str, "1") == 0) return 1;
+ str = getenv ("SKIP_TEST_TAIL");
+ if (str && strcmp (str, "1") == 0) return 1;
+ return 0;
+}
+
+static int test_tail_0 (void)
+{
+ if (test_tail_0_skip ()) {
+ printf ("%s skipped (reason: environment variable set)\n", "test_tail_0");
+ return 0;
+ }
+
+ /* InitBasicFS for test_tail_0: create ext2 on /dev/sda1 */
+ {
+ char device[] = "/dev/sda";
+ int r;
+ suppress_error = 0;
+ r = guestfs_blockdev_setrw (g, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda";
+ char lines_0[] = ",";
+ char *lines[] = {
+ lines_0,
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, device, 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char fstype[] = "ext2";
+ char device[] = "/dev/sda1";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, fstype, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda1";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for tail (0) */
+ {
+ char options[] = "ro";
+ char vfstype[] = "squashfs";
+ char device[] = "/dev/sdd";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount_vfs (g, options, vfstype, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char path[] = "/10klines";
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_tail (g, path);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_tail_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9990abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[0], expected) != 0) {
+ fprintf (stderr, "test_tail_0: expected \"%s\" but got \"%s\"\n", expected, r[0]);
+ return -1;
+ }
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_tail_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9991abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[1], expected) != 0) {
+ fprintf (stderr, "test_tail_0: expected \"%s\" but got \"%s\"\n", expected, r[1]);
+ return -1;
+ }
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_tail_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9992abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[2], expected) != 0) {
+ fprintf (stderr, "test_tail_0: expected \"%s\" but got \"%s\"\n", expected, r[2]);
+ return -1;
+ }
+ }
+ if (!r[3]) {
+ fprintf (stderr, "test_tail_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9993abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[3], expected) != 0) {
+ fprintf (stderr, "test_tail_0: expected \"%s\" but got \"%s\"\n", expected, r[3]);
+ return -1;
+ }
+ }
+ if (!r[4]) {
+ fprintf (stderr, "test_tail_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9994abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[4], expected) != 0) {
+ fprintf (stderr, "test_tail_0: expected \"%s\" but got \"%s\"\n", expected, r[4]);
+ return -1;
+ }
+ }
+ if (!r[5]) {
+ fprintf (stderr, "test_tail_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9995abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[5], expected) != 0) {
+ fprintf (stderr, "test_tail_0: expected \"%s\" but got \"%s\"\n", expected, r[5]);
+ return -1;
+ }
+ }
+ if (!r[6]) {
+ fprintf (stderr, "test_tail_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9996abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[6], expected) != 0) {
+ fprintf (stderr, "test_tail_0: expected \"%s\" but got \"%s\"\n", expected, r[6]);
+ return -1;
+ }
+ }
+ if (!r[7]) {
+ fprintf (stderr, "test_tail_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9997abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[7], expected) != 0) {
+ fprintf (stderr, "test_tail_0: expected \"%s\" but got \"%s\"\n", expected, r[7]);
+ return -1;
+ }
+ }
+ if (!r[8]) {
+ fprintf (stderr, "test_tail_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9998abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[8], expected) != 0) {
+ fprintf (stderr, "test_tail_0: expected \"%s\" but got \"%s\"\n", expected, r[8]);
+ return -1;
+ }
+ }
+ if (!r[9]) {
+ fprintf (stderr, "test_tail_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9999abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[9], expected) != 0) {
+ fprintf (stderr, "test_tail_0: expected \"%s\" but got \"%s\"\n", expected, r[9]);
+ return -1;
+ }
+ }
+ if (r[10] != NULL) {
+ fprintf (stderr, "test_tail_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_head_n_0_skip (void)
+{
+ const char *str;
+
+ str = getenv ("TEST_ONLY");
+ if (str)
+ return strstr (str, "head_n") == NULL;
+ str = getenv ("SKIP_TEST_HEAD_N_0");
+ if (str && strcmp (str, "1") == 0) return 1;
+ str = getenv ("SKIP_TEST_HEAD_N");
+ if (str && strcmp (str, "1") == 0) return 1;
+ return 0;
+}
+
+static int test_head_n_0 (void)
+{
+ if (test_head_n_0_skip ()) {
+ printf ("%s skipped (reason: environment variable set)\n", "test_head_n_0");
+ return 0;
+ }
+
+ /* InitBasicFS for test_head_n_0: create ext2 on /dev/sda1 */
+ {
+ char device[] = "/dev/sda";
+ int r;
+ suppress_error = 0;
+ r = guestfs_blockdev_setrw (g, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda";
+ char lines_0[] = ",";
+ char *lines[] = {
+ lines_0,
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, device, 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char fstype[] = "ext2";
+ char device[] = "/dev/sda1";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, fstype, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda1";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for head_n (0) */
+ {
+ char options[] = "ro";
+ char vfstype[] = "squashfs";
+ char device[] = "/dev/sdd";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount_vfs (g, options, vfstype, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char path[] = "/10klines";
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_head_n (g, 3, path);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_head_n_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "0abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[0], expected) != 0) {
+ fprintf (stderr, "test_head_n_0: expected \"%s\" but got \"%s\"\n", expected, r[0]);
+ return -1;
+ }
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_head_n_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "1abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[1], expected) != 0) {
+ fprintf (stderr, "test_head_n_0: expected \"%s\" but got \"%s\"\n", expected, r[1]);
+ return -1;
+ }
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_head_n_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "2abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[2], expected) != 0) {
+ fprintf (stderr, "test_head_n_0: expected \"%s\" but got \"%s\"\n", expected, r[2]);
+ return -1;
+ }
+ }
+ if (r[3] != NULL) {
+ fprintf (stderr, "test_head_n_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_head_n_1_skip (void)
+{
+ const char *str;
+
+ str = getenv ("TEST_ONLY");
+ if (str)
+ return strstr (str, "head_n") == NULL;
+ str = getenv ("SKIP_TEST_HEAD_N_1");
+ if (str && strcmp (str, "1") == 0) return 1;
+ str = getenv ("SKIP_TEST_HEAD_N");
+ if (str && strcmp (str, "1") == 0) return 1;
+ return 0;
+}
+
+static int test_head_n_1 (void)
+{
+ if (test_head_n_1_skip ()) {
+ printf ("%s skipped (reason: environment variable set)\n", "test_head_n_1");
+ return 0;
+ }
+
+ /* InitBasicFS for test_head_n_1: create ext2 on /dev/sda1 */
+ {
+ char device[] = "/dev/sda";
+ int r;
+ suppress_error = 0;
+ r = guestfs_blockdev_setrw (g, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda";
+ char lines_0[] = ",";
+ char *lines[] = {
+ lines_0,
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, device, 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char fstype[] = "ext2";
+ char device[] = "/dev/sda1";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, fstype, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda1";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for head_n (1) */
+ {
+ char options[] = "ro";
+ char vfstype[] = "squashfs";
+ char device[] = "/dev/sdd";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount_vfs (g, options, vfstype, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char path[] = "/10klines";
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_head_n (g, -9997, path);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_head_n_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "0abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[0], expected) != 0) {
+ fprintf (stderr, "test_head_n_1: expected \"%s\" but got \"%s\"\n", expected, r[0]);
+ return -1;
+ }
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_head_n_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "1abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[1], expected) != 0) {
+ fprintf (stderr, "test_head_n_1: expected \"%s\" but got \"%s\"\n", expected, r[1]);
+ return -1;
+ }
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_head_n_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "2abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[2], expected) != 0) {
+ fprintf (stderr, "test_head_n_1: expected \"%s\" but got \"%s\"\n", expected, r[2]);
+ return -1;
+ }
+ }
+ if (r[3] != NULL) {
+ fprintf (stderr, "test_head_n_1: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_head_n_2_skip (void)
+{
+ const char *str;
+
+ str = getenv ("TEST_ONLY");
+ if (str)
+ return strstr (str, "head_n") == NULL;
+ str = getenv ("SKIP_TEST_HEAD_N_2");
+ if (str && strcmp (str, "1") == 0) return 1;
+ str = getenv ("SKIP_TEST_HEAD_N");
+ if (str && strcmp (str, "1") == 0) return 1;
+ return 0;
+}
+
+static int test_head_n_2 (void)
+{
+ if (test_head_n_2_skip ()) {
+ printf ("%s skipped (reason: environment variable set)\n", "test_head_n_2");
+ return 0;
+ }
+
+ /* InitBasicFS for test_head_n_2: create ext2 on /dev/sda1 */
+ {
+ char device[] = "/dev/sda";
+ int r;
+ suppress_error = 0;
+ r = guestfs_blockdev_setrw (g, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda";
+ char lines_0[] = ",";
+ char *lines[] = {
+ lines_0,
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, device, 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char fstype[] = "ext2";
+ char device[] = "/dev/sda1";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, fstype, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda1";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for head_n (2) */
+ {
+ char options[] = "ro";
+ char vfstype[] = "squashfs";
+ char device[] = "/dev/sdd";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount_vfs (g, options, vfstype, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char path[] = "/10klines";
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_head_n (g, 0, path);
+ if (r == NULL)
+ return -1;
+ if (r[0] != NULL) {
+ fprintf (stderr, "test_head_n_2: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_head_0_skip (void)
+{
+ const char *str;
+
+ str = getenv ("TEST_ONLY");
+ if (str)
+ return strstr (str, "head") == NULL;
+ str = getenv ("SKIP_TEST_HEAD_0");
+ if (str && strcmp (str, "1") == 0) return 1;
+ str = getenv ("SKIP_TEST_HEAD");
+ if (str && strcmp (str, "1") == 0) return 1;
+ return 0;
+}
+
+static int test_head_0 (void)
+{
+ if (test_head_0_skip ()) {
+ printf ("%s skipped (reason: environment variable set)\n", "test_head_0");
+ return 0;
+ }
+
+ /* InitBasicFS for test_head_0: create ext2 on /dev/sda1 */
+ {
+ char device[] = "/dev/sda";
+ int r;
+ suppress_error = 0;
+ r = guestfs_blockdev_setrw (g, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda";
+ char lines_0[] = ",";
+ char *lines[] = {
+ lines_0,
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, device, 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char fstype[] = "ext2";
+ char device[] = "/dev/sda1";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, fstype, device);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char device[] = "/dev/sda1";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for head (0) */
+ {
+ char options[] = "ro";
+ char vfstype[] = "squashfs";
+ char device[] = "/dev/sdd";
+ char mountpoint[] = "/";
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount_vfs (g, options, vfstype, device, mountpoint);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char path[] = "/10klines";
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_head (g, path);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_head_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "0abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[0], expected) != 0) {
+ fprintf (stderr, "test_head_0: expected \"%s\" but got \"%s\"\n", expected, r[0]);
+ return -1;
+ }
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_head_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "1abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[1], expected) != 0) {
+ fprintf (stderr, "test_head_0: expected \"%s\" but got \"%s\"\n", expected, r[1]);
+ return -1;
+ }
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_head_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "2abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[2], expected) != 0) {
+ fprintf (stderr, "test_head_0: expected \"%s\" but got \"%s\"\n", expected, r[2]);
+ return -1;
+ }
+ }
+ if (!r[3]) {
+ fprintf (stderr, "test_head_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "3abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[3], expected) != 0) {
+ fprintf (stderr, "test_head_0: expected \"%s\" but got \"%s\"\n", expected, r[3]);
+ return -1;
+ }
+ }
+ if (!r[4]) {
+ fprintf (stderr, "test_head_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "4abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[4], expected) != 0) {
+ fprintf (stderr, "test_head_0: expected \"%s\" but got \"%s\"\n", expected, r[4]);
+ return -1;
+ }
+ }
+ if (!r[5]) {
+ fprintf (stderr, "test_head_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "5abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[5], expected) != 0) {
+ fprintf (stderr, "test_head_0: expected \"%s\" but got \"%s\"\n", expected, r[5]);
+ return -1;
+ }
+ }
+ if (!r[6]) {
+ fprintf (stderr, "test_head_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "6abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[6], expected) != 0) {
+ fprintf (stderr, "test_head_0: expected \"%s\" but got \"%s\"\n", expected, r[6]);
+ return -1;
+ }
+ }
+ if (!r[7]) {
+ fprintf (stderr, "test_head_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "7abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[7], expected) != 0) {
+ fprintf (stderr, "test_head_0: expected \"%s\" but got \"%s\"\n", expected, r[7]);
+ return -1;
+ }
+ }
+ if (!r[8]) {
+ fprintf (stderr, "test_head_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "8abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[8], expected) != 0) {
+ fprintf (stderr, "test_head_0: expected \"%s\" but got \"%s\"\n", expected, r[8]);
+ return -1;
+ }
+ }
+ if (!r[9]) {
+ fprintf (stderr, "test_head_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ {
+ char expected[] = "9abcdefghijklmnopqrstuvwxyz";
+ if (strcmp (r[9], expected) != 0) {
+ fprintf (stderr, "test_head_0: expected \"%s\" but got \"%s\"\n", expected, r[9]);
+ return -1;
+ }
+ }
+ if (r[10] != NULL) {
+ fprintf (stderr, "test_head_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
static int test_wc_c_0_skip (void)
{
const char *str;
/* Cancel previous alarm. */
alarm (0);
- nr_tests = 156;
+ nr_tests = 164;
test_num++;
+ printf ("%3d/%3d test_tail_n_0\n", test_num, nr_tests);
+ if (test_tail_n_0 () == -1) {
+ printf ("test_tail_n_0 FAILED\n");
+ failed++;
+ }
+ test_num++;
+ printf ("%3d/%3d test_tail_n_1\n", test_num, nr_tests);
+ if (test_tail_n_1 () == -1) {
+ printf ("test_tail_n_1 FAILED\n");
+ failed++;
+ }
+ test_num++;
+ printf ("%3d/%3d test_tail_n_2\n", test_num, nr_tests);
+ if (test_tail_n_2 () == -1) {
+ printf ("test_tail_n_2 FAILED\n");
+ failed++;
+ }
+ test_num++;
+ printf ("%3d/%3d test_tail_0\n", test_num, nr_tests);
+ if (test_tail_0 () == -1) {
+ printf ("test_tail_0 FAILED\n");
+ failed++;
+ }
+ test_num++;
+ printf ("%3d/%3d test_head_n_0\n", test_num, nr_tests);
+ if (test_head_n_0 () == -1) {
+ printf ("test_head_n_0 FAILED\n");
+ failed++;
+ }
+ test_num++;
+ printf ("%3d/%3d test_head_n_1\n", test_num, nr_tests);
+ if (test_head_n_1 () == -1) {
+ printf ("test_head_n_1 FAILED\n");
+ failed++;
+ }
+ test_num++;
+ printf ("%3d/%3d test_head_n_2\n", test_num, nr_tests);
+ if (test_head_n_2 () == -1) {
+ printf ("test_head_n_2 FAILED\n");
+ failed++;
+ }
+ test_num++;
+ printf ("%3d/%3d test_head_0\n", test_num, nr_tests);
+ if (test_head_0 () == -1) {
+ printf ("test_head_0 FAILED\n");
+ failed++;
+ }
+ test_num++;
printf ("%3d/%3d test_wc_c_0\n", test_num, nr_tests);
if (test_wc_c_0 () == -1) {
printf ("test_wc_c_0 FAILED\n");
extern char *do_hexdump (char *path);
extern int do_zerofree (char *device);
extern int do_pvresize (char *device);
-extern int do_sfdisk_N (char *device, int n, int cyls, int heads, int sectors, char *line);
+extern int do_sfdisk_N (char *device, int partnum, int cyls, int heads, int sectors, char *line);
extern char *do_sfdisk_l (char *device);
extern char *do_sfdisk_kernel_geometry (char *device);
extern char *do_sfdisk_disk_geometry (char *device);
extern int do_wc_l (char *path);
extern int do_wc_w (char *path);
extern int do_wc_c (char *path);
+extern char **do_head (char *path);
+extern char **do_head_n (int nrlines, char *path);
+extern char **do_tail (char *path);
+extern char **do_tail_n (int nrlines, char *path);
int r;
struct guestfs_sfdisk_N_args args;
char *device;
- int n;
+ int partnum;
int cyls;
int heads;
int sectors;
return;
}
device = args.device;
- n = args.n;
+ partnum = args.partnum;
cyls = args.cyls;
heads = args.heads;
sectors = args.sectors;
line = args.line;
- r = do_sfdisk_N (device, n, cyls, heads, sectors, line);
+ r = do_sfdisk_N (device, partnum, cyls, heads, sectors, line);
if (r == -1)
/* do_sfdisk_N has already called reply_with_error */
goto done;
xdr_free ((xdrproc_t) xdr_guestfs_wc_c_args, (char *) &args);
}
+static void head_stub (XDR *xdr_in)
+{
+ char **r;
+ struct guestfs_head_args args;
+ char *path;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_head_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "head");
+ return;
+ }
+ path = args.path;
+
+ r = do_head (path);
+ if (r == NULL)
+ /* do_head has already called reply_with_error */
+ goto done;
+
+ struct guestfs_head_ret ret;
+ ret.lines.lines_len = count_strings (r);
+ ret.lines.lines_val = r;
+ reply ((xdrproc_t) &xdr_guestfs_head_ret, (char *) &ret);
+ free_strings (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_head_args, (char *) &args);
+}
+
+static void head_n_stub (XDR *xdr_in)
+{
+ char **r;
+ struct guestfs_head_n_args args;
+ int nrlines;
+ char *path;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_head_n_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "head_n");
+ return;
+ }
+ nrlines = args.nrlines;
+ path = args.path;
+
+ r = do_head_n (nrlines, path);
+ if (r == NULL)
+ /* do_head_n has already called reply_with_error */
+ goto done;
+
+ struct guestfs_head_n_ret ret;
+ ret.lines.lines_len = count_strings (r);
+ ret.lines.lines_val = r;
+ reply ((xdrproc_t) &xdr_guestfs_head_n_ret, (char *) &ret);
+ free_strings (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_head_n_args, (char *) &args);
+}
+
+static void tail_stub (XDR *xdr_in)
+{
+ char **r;
+ struct guestfs_tail_args args;
+ char *path;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_tail_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "tail");
+ return;
+ }
+ path = args.path;
+
+ r = do_tail (path);
+ if (r == NULL)
+ /* do_tail has already called reply_with_error */
+ goto done;
+
+ struct guestfs_tail_ret ret;
+ ret.lines.lines_len = count_strings (r);
+ ret.lines.lines_val = r;
+ reply ((xdrproc_t) &xdr_guestfs_tail_ret, (char *) &ret);
+ free_strings (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_tail_args, (char *) &args);
+}
+
+static void tail_n_stub (XDR *xdr_in)
+{
+ char **r;
+ struct guestfs_tail_n_args args;
+ int nrlines;
+ char *path;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_tail_n_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "tail_n");
+ return;
+ }
+ nrlines = args.nrlines;
+ path = args.path;
+
+ r = do_tail_n (nrlines, path);
+ if (r == NULL)
+ /* do_tail_n has already called reply_with_error */
+ goto done;
+
+ struct guestfs_tail_n_ret ret;
+ ret.lines.lines_len = count_strings (r);
+ ret.lines.lines_val = r;
+ reply ((xdrproc_t) &xdr_guestfs_tail_n_ret, (char *) &ret);
+ free_strings (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_tail_n_args, (char *) &args);
+}
+
void dispatch_incoming_message (XDR *xdr_in)
{
switch (proc_nr) {
case GUESTFS_PROC_WC_C:
wc_c_stub (xdr_in);
break;
+ case GUESTFS_PROC_HEAD:
+ head_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_HEAD_N:
+ head_n_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_TAIL:
+ tail_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_TAIL_N:
+ tail_n_stub (xdr_in);
+ break;
default:
reply_with_error ("dispatch_incoming_message: unknown procedure number %d, set LIBGUESTFS_PATH to point to the matching libguestfs appliance directory", proc_nr);
}
printf ("%-20s %s\n", "get-verbose", "get verbose mode");
printf ("%-20s %s\n", "glob-expand", "expand a wildcard path");
printf ("%-20s %s\n", "grub-install", "install GRUB");
+ printf ("%-20s %s\n", "head", "return first 10 lines of a file");
+ printf ("%-20s %s\n", "head-n", "return first N lines of a file");
printf ("%-20s %s\n", "hexdump", "dump a file in hexadecimal");
printf ("%-20s %s\n", "is-busy", "is busy processing a command");
printf ("%-20s %s\n", "is-config", "is in configuration state");
printf ("%-20s %s\n", "strings", "print the printable strings in a file");
printf ("%-20s %s\n", "strings-e", "print the printable strings in a file");
printf ("%-20s %s\n", "sync", "sync disks, writes are flushed through to the disk image");
+ printf ("%-20s %s\n", "tail", "return last 10 lines of a file");
+ printf ("%-20s %s\n", "tail-n", "return last N lines of a file");
printf ("%-20s %s\n", "tar-in", "unpack tarfile to directory");
printf ("%-20s %s\n", "tar-out", "pack directory into tarfile");
printf ("%-20s %s\n", "tgz-in", "unpack compressed tarball to directory");
pod2text ("pvresize - resize an LVM physical volume", " pvresize <device>\n\nThis resizes (expands or shrinks) an existing LVM physical\nvolume to match the new size of the underlying device.");
else
if (strcasecmp (cmd, "sfdisk_N") == 0 || strcasecmp (cmd, "sfdisk-N") == 0)
- pod2text ("sfdisk-N - modify a single partition on a block device", " sfdisk-N <device> <n> <cyls> <heads> <sectors> <line>\n\nThis runs L<sfdisk(8)> option to modify just the single\npartition C<n> (note: C<n> counts from 1).\n\nFor other parameters, see C<sfdisk>. You should usually\npass C<0> for the cyls/heads/sectors parameters.\n\nB<This command is dangerous. Without careful use you\ncan easily destroy all your data>.");
+ pod2text ("sfdisk-N - modify a single partition on a block device", " sfdisk-N <device> <partnum> <cyls> <heads> <sectors> <line>\n\nThis runs L<sfdisk(8)> option to modify just the single\npartition C<n> (note: C<n> counts from 1).\n\nFor other parameters, see C<sfdisk>. You should usually\npass C<0> for the cyls/heads/sectors parameters.\n\nB<This command is dangerous. Without careful use you\ncan easily destroy all your data>.");
else
if (strcasecmp (cmd, "sfdisk_l") == 0 || strcasecmp (cmd, "sfdisk-l") == 0)
pod2text ("sfdisk-l - display the partition table", " sfdisk-l <device>\n\nThis displays the partition table on C<device>, in the\nhuman-readable output of the L<sfdisk(8)> command. It is\nnot intended to be parsed.");
if (strcasecmp (cmd, "wc_c") == 0 || strcasecmp (cmd, "wc-c") == 0)
pod2text ("wc-c - count characters in a file", " wc-c <path>\n\nThis command counts the characters in a file, using the\nC<wc -c> external command.");
else
+ if (strcasecmp (cmd, "head") == 0)
+ pod2text ("head - return first 10 lines of a file", " head <path>\n\nThis command returns up to the first 10 lines of a file as\na list of strings.\n\nBecause of the message protocol, there is a transfer limit \nof somewhere between 2MB and 4MB. To transfer large files you should use\nFTP.");
+ else
+ if (strcasecmp (cmd, "head_n") == 0 || strcasecmp (cmd, "head-n") == 0)
+ pod2text ("head-n - return first N lines of a file", " head-n <nrlines> <path>\n\nIf the parameter C<nrlines> is a positive number, this returns the first\nC<nrlines> lines of the file C<path>.\n\nIf the parameter C<nrlines> is a negative number, this returns lines\nfrom the file C<path>, excluding the last C<nrlines> lines.\n\nIf the parameter C<nrlines> is zero, this returns an empty list.\n\nBecause of the message protocol, there is a transfer limit \nof somewhere between 2MB and 4MB. To transfer large files you should use\nFTP.");
+ else
+ if (strcasecmp (cmd, "tail") == 0)
+ pod2text ("tail - return last 10 lines of a file", " tail <path>\n\nThis command returns up to the last 10 lines of a file as\na list of strings.\n\nBecause of the message protocol, there is a transfer limit \nof somewhere between 2MB and 4MB. To transfer large files you should use\nFTP.");
+ else
+ if (strcasecmp (cmd, "tail_n") == 0 || strcasecmp (cmd, "tail-n") == 0)
+ pod2text ("tail-n - return last N lines of a file", " tail-n <nrlines> <path>\n\nIf the parameter C<nrlines> is a positive number, this returns the last\nC<nrlines> lines of the file C<path>.\n\nIf the parameter C<nrlines> is a negative number, this returns lines\nfrom the file C<path>, starting with the C<-nrlines>th line.\n\nIf the parameter C<nrlines> is zero, this returns an empty list.\n\nBecause of the message protocol, there is a transfer limit \nof somewhere between 2MB and 4MB. To transfer large files you should use\nFTP.");
+ else
display_builtin_command (cmd);
}
{
int r;
const char *device;
- int n;
+ int partnum;
int cyls;
int heads;
int sectors;
return -1;
}
device = argv[0];
- n = atoi (argv[1]);
+ partnum = atoi (argv[1]);
cyls = atoi (argv[2]);
heads = atoi (argv[3]);
sectors = atoi (argv[4]);
line = argv[5];
- r = guestfs_sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ r = guestfs_sfdisk_N (g, device, partnum, cyls, heads, sectors, line);
return r;
}
return 0;
}
+static int run_head (const char *cmd, int argc, char *argv[])
+{
+ char **r;
+ const char *path;
+ if (argc != 1) {
+ fprintf (stderr, "%s should have 1 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ path = argv[0];
+ r = guestfs_head (g, path);
+ if (r == NULL) return -1;
+ print_strings (r);
+ free_strings (r);
+ return 0;
+}
+
+static int run_head_n (const char *cmd, int argc, char *argv[])
+{
+ char **r;
+ int nrlines;
+ const char *path;
+ if (argc != 2) {
+ fprintf (stderr, "%s should have 2 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ nrlines = atoi (argv[0]);
+ path = argv[1];
+ r = guestfs_head_n (g, nrlines, path);
+ if (r == NULL) return -1;
+ print_strings (r);
+ free_strings (r);
+ return 0;
+}
+
+static int run_tail (const char *cmd, int argc, char *argv[])
+{
+ char **r;
+ const char *path;
+ if (argc != 1) {
+ fprintf (stderr, "%s should have 1 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ path = argv[0];
+ r = guestfs_tail (g, path);
+ if (r == NULL) return -1;
+ print_strings (r);
+ free_strings (r);
+ return 0;
+}
+
+static int run_tail_n (const char *cmd, int argc, char *argv[])
+{
+ char **r;
+ int nrlines;
+ const char *path;
+ if (argc != 2) {
+ fprintf (stderr, "%s should have 2 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ nrlines = atoi (argv[0]);
+ path = argv[1];
+ r = guestfs_tail_n (g, nrlines, path);
+ if (r == NULL) return -1;
+ print_strings (r);
+ free_strings (r);
+ return 0;
+}
+
int run_action (const char *cmd, int argc, char *argv[])
{
if (strcasecmp (cmd, "launch") == 0 || strcasecmp (cmd, "run") == 0)
if (strcasecmp (cmd, "wc_c") == 0 || strcasecmp (cmd, "wc-c") == 0)
return run_wc_c (cmd, argc, argv);
else
+ if (strcasecmp (cmd, "head") == 0)
+ return run_head (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "head_n") == 0 || strcasecmp (cmd, "head-n") == 0)
+ return run_head_n (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "tail") == 0)
+ return run_tail (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "tail_n") == 0 || strcasecmp (cmd, "tail-n") == 0)
+ return run_tail_n (cmd, argc, argv);
+ else
{
fprintf (stderr, "%s: unknown command\n", cmd);
return -1;
"wc-l",
"wc-w",
"wc-c",
+ "head",
+ "head-n",
+ "tail",
+ "tail-n",
NULL
};
This command installs GRUB (the Grand Unified Bootloader) on
C<device>, with the root directory being C<root>.
+=head2 head
+
+ head path
+
+This command returns up to the first 10 lines of a file as
+a list of strings.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
+=head2 head-n
+
+ head-n nrlines path
+
+If the parameter C<nrlines> is a positive number, this returns the first
+C<nrlines> lines of the file C<path>.
+
+If the parameter C<nrlines> is a negative number, this returns lines
+from the file C<path>, excluding the last C<nrlines> lines.
+
+If the parameter C<nrlines> is zero, this returns an empty list.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
=head2 hexdump
hexdump path
=head2 sfdisk-N
- sfdisk-N device n cyls heads sectors line
+ sfdisk-N device partnum cyls heads sectors line
This runs L<sfdisk(8)> option to modify just the single
partition C<n> (note: C<n> counts from 1).
You should always call this if you have modified a disk image, before
closing the handle.
+=head2 tail
+
+ tail path
+
+This command returns up to the last 10 lines of a file as
+a list of strings.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
+=head2 tail-n
+
+ tail-n nrlines path
+
+If the parameter C<nrlines> is a positive number, this returns the last
+C<nrlines> lines of the file C<path>.
+
+If the parameter C<nrlines> is a negative number, this returns lines
+from the file C<path>, starting with the C<-nrlines>th line.
+
+If the parameter C<nrlines> is zero, this returns an empty list.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
=head2 tar-in
tar-in (tarfile|-) directory
This function returns 0 on success or -1 on error.
+=head2 guestfs_head
+
+ char **guestfs_head (guestfs_h *handle,
+ const char *path);
+
+This command returns up to the first 10 lines of a file as
+a list of strings.
+
+This function returns a NULL-terminated array of strings
+(like L<environ(3)>), or NULL if there was an error.
+I<The caller must free the strings and the array after use>.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
+=head2 guestfs_head_n
+
+ char **guestfs_head_n (guestfs_h *handle,
+ int nrlines,
+ const char *path);
+
+If the parameter C<nrlines> is a positive number, this returns the first
+C<nrlines> lines of the file C<path>.
+
+If the parameter C<nrlines> is a negative number, this returns lines
+from the file C<path>, excluding the last C<nrlines> lines.
+
+If the parameter C<nrlines> is zero, this returns an empty list.
+
+This function returns a NULL-terminated array of strings
+(like L<environ(3)>), or NULL if there was an error.
+I<The caller must free the strings and the array after use>.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
=head2 guestfs_hexdump
char *guestfs_hexdump (guestfs_h *handle,
int guestfs_sfdisk_N (guestfs_h *handle,
const char *device,
- int n,
+ int partnum,
int cyls,
int heads,
int sectors,
This function returns 0 on success or -1 on error.
+=head2 guestfs_tail
+
+ char **guestfs_tail (guestfs_h *handle,
+ const char *path);
+
+This command returns up to the last 10 lines of a file as
+a list of strings.
+
+This function returns a NULL-terminated array of strings
+(like L<environ(3)>), or NULL if there was an error.
+I<The caller must free the strings and the array after use>.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
+=head2 guestfs_tail_n
+
+ char **guestfs_tail_n (guestfs_h *handle,
+ int nrlines,
+ const char *path);
+
+If the parameter C<nrlines> is a positive number, this returns the last
+C<nrlines> lines of the file C<path>.
+
+If the parameter C<nrlines> is a negative number, this returns lines
+from the file C<path>, starting with the C<-nrlines>th line.
+
+If the parameter C<nrlines> is zero, this returns an empty list.
+
+This function returns a NULL-terminated array of strings
+(like L<environ(3)>), or NULL if there was an error.
+I<The caller must free the strings and the array after use>.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
=head2 guestfs_tar_in
int guestfs_tar_in (guestfs_h *handle,
:: GuestfsP -> CString -> CInt -> CInt -> CInt -> CInt -> CString -> IO (CInt)
sfdisk_N :: GuestfsH -> String -> Int -> Int -> Int -> Int -> String -> IO ()
-sfdisk_N h device n cyls heads sectors line = do
- r <- withCString device $ \device -> withCString line $ \line -> withForeignPtr h (\p -> c_sfdisk_N p device (fromIntegral n) (fromIntegral cyls) (fromIntegral heads) (fromIntegral sectors) line)
+sfdisk_N h device partnum cyls heads sectors line = do
+ r <- withCString device $ \device -> withCString line $ \line -> withForeignPtr h (\p -> c_sfdisk_N p device (fromIntegral partnum) (fromIntegral cyls) (fromIntegral heads) (fromIntegral sectors) line)
if (r == -1)
then do
err <- last_error h
rm -f $@ $@-t
i=0; \
while [ $$i -lt 10000 ]; do \
- echo "abcdefghijklmnopqrstuvwxyz"; \
+ echo "$${i}abcdefghijklmnopqrstuvwxyz"; \
i=$$(($$i+1)); \
done > $@-t
mv $@-t $@
* <p>
* @throws LibGuestFSException
*/
- public void sfdisk_N (String device, int n, int cyls, int heads, int sectors, String line)
+ public void sfdisk_N (String device, int partnum, int cyls, int heads, int sectors, String line)
throws LibGuestFSException
{
if (g == 0)
throw new LibGuestFSException ("sfdisk_N: handle is closed");
- _sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ _sfdisk_N (g, device, partnum, cyls, heads, sectors, line);
}
- private native void _sfdisk_N (long g, String device, int n, int cyls, int heads, int sectors, String line)
+ private native void _sfdisk_N (long g, String device, int partnum, int cyls, int heads, int sectors, String line)
throws LibGuestFSException;
/**
private native int _wc_c (long g, String path)
throws LibGuestFSException;
+ /**
+ * return first 10 lines of a file
+ * <p>
+ * This command returns up to the first 10 lines of a file
+ * as a list of strings.
+ * <p>
+ * Because of the message protocol, there is a transfer
+ * limit of somewhere between 2MB and 4MB. To transfer
+ * large files you should use FTP.
+ * <p>
+ * @throws LibGuestFSException
+ */
+ public String[] head (String path)
+ throws LibGuestFSException
+ {
+ if (g == 0)
+ throw new LibGuestFSException ("head: handle is closed");
+ return _head (g, path);
+ }
+ private native String[] _head (long g, String path)
+ throws LibGuestFSException;
+
+ /**
+ * return first N lines of a file
+ * <p>
+ * If the parameter "nrlines" is a positive number, this
+ * returns the first "nrlines" lines of the file "path".
+ * <p>
+ * If the parameter "nrlines" is a negative number, this
+ * returns lines from the file "path", excluding the last
+ * "nrlines" lines.
+ * <p>
+ * If the parameter "nrlines" is zero, this returns an
+ * empty list.
+ * <p>
+ * Because of the message protocol, there is a transfer
+ * limit of somewhere between 2MB and 4MB. To transfer
+ * large files you should use FTP.
+ * <p>
+ * @throws LibGuestFSException
+ */
+ public String[] head_n (int nrlines, String path)
+ throws LibGuestFSException
+ {
+ if (g == 0)
+ throw new LibGuestFSException ("head_n: handle is closed");
+ return _head_n (g, nrlines, path);
+ }
+ private native String[] _head_n (long g, int nrlines, String path)
+ throws LibGuestFSException;
+
+ /**
+ * return last 10 lines of a file
+ * <p>
+ * This command returns up to the last 10 lines of a file
+ * as a list of strings.
+ * <p>
+ * Because of the message protocol, there is a transfer
+ * limit of somewhere between 2MB and 4MB. To transfer
+ * large files you should use FTP.
+ * <p>
+ * @throws LibGuestFSException
+ */
+ public String[] tail (String path)
+ throws LibGuestFSException
+ {
+ if (g == 0)
+ throw new LibGuestFSException ("tail: handle is closed");
+ return _tail (g, path);
+ }
+ private native String[] _tail (long g, String path)
+ throws LibGuestFSException;
+
+ /**
+ * return last N lines of a file
+ * <p>
+ * If the parameter "nrlines" is a positive number, this
+ * returns the last "nrlines" lines of the file "path".
+ * <p>
+ * If the parameter "nrlines" is a negative number, this
+ * returns lines from the file "path", starting with the
+ * "-nrlines"th line.
+ * <p>
+ * If the parameter "nrlines" is zero, this returns an
+ * empty list.
+ * <p>
+ * Because of the message protocol, there is a transfer
+ * limit of somewhere between 2MB and 4MB. To transfer
+ * large files you should use FTP.
+ * <p>
+ * @throws LibGuestFSException
+ */
+ public String[] tail_n (int nrlines, String path)
+ throws LibGuestFSException
+ {
+ if (g == 0)
+ throw new LibGuestFSException ("tail_n: handle is closed");
+ return _tail_n (g, nrlines, path);
+ }
+ private native String[] _tail_n (long g, int nrlines, String path)
+ throws LibGuestFSException;
+
}
JNIEXPORT void JNICALL
Java_com_redhat_et_libguestfs_GuestFS__1sfdisk_1N
- (JNIEnv *env, jobject obj, jlong jg, jstring jdevice, jint jn, jint jcyls, jint jheads, jint jsectors, jstring jline)
+ (JNIEnv *env, jobject obj, jlong jg, jstring jdevice, jint jpartnum, jint jcyls, jint jheads, jint jsectors, jstring jline)
{
guestfs_h *g = (guestfs_h *) (long) jg;
int r;
const char *device;
- int n;
+ int partnum;
int cyls;
int heads;
int sectors;
const char *line;
device = (*env)->GetStringUTFChars (env, jdevice, NULL);
- n = jn;
+ partnum = jpartnum;
cyls = jcyls;
heads = jheads;
sectors = jsectors;
line = (*env)->GetStringUTFChars (env, jline, NULL);
- r = guestfs_sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ r = guestfs_sfdisk_N (g, device, partnum, cyls, heads, sectors, line);
(*env)->ReleaseStringUTFChars (env, jdevice, device);
(*env)->ReleaseStringUTFChars (env, jline, line);
if (r == -1) {
return (jint) r;
}
+JNIEXPORT jobjectArray JNICALL
+Java_com_redhat_et_libguestfs_GuestFS__1head
+ (JNIEnv *env, jobject obj, jlong jg, jstring jpath)
+{
+ guestfs_h *g = (guestfs_h *) (long) jg;
+ jobjectArray jr;
+ int r_len;
+ jclass cl;
+ jstring jstr;
+ char **r;
+ const char *path;
+ int i;
+
+ path = (*env)->GetStringUTFChars (env, jpath, NULL);
+ r = guestfs_head (g, path);
+ (*env)->ReleaseStringUTFChars (env, jpath, path);
+ if (r == NULL) {
+ throw_exception (env, guestfs_last_error (g));
+ return NULL;
+ }
+ for (r_len = 0; r[r_len] != NULL; ++r_len) ;
+ cl = (*env)->FindClass (env, "java/lang/String");
+ jstr = (*env)->NewStringUTF (env, "");
+ jr = (*env)->NewObjectArray (env, r_len, cl, jstr);
+ for (i = 0; i < r_len; ++i) {
+ jstr = (*env)->NewStringUTF (env, r[i]);
+ (*env)->SetObjectArrayElement (env, jr, i, jstr);
+ free (r[i]);
+ }
+ free (r);
+ return jr;
+}
+
+JNIEXPORT jobjectArray JNICALL
+Java_com_redhat_et_libguestfs_GuestFS__1head_1n
+ (JNIEnv *env, jobject obj, jlong jg, jint jnrlines, jstring jpath)
+{
+ guestfs_h *g = (guestfs_h *) (long) jg;
+ jobjectArray jr;
+ int r_len;
+ jclass cl;
+ jstring jstr;
+ char **r;
+ int nrlines;
+ const char *path;
+ int i;
+
+ nrlines = jnrlines;
+ path = (*env)->GetStringUTFChars (env, jpath, NULL);
+ r = guestfs_head_n (g, nrlines, path);
+ (*env)->ReleaseStringUTFChars (env, jpath, path);
+ if (r == NULL) {
+ throw_exception (env, guestfs_last_error (g));
+ return NULL;
+ }
+ for (r_len = 0; r[r_len] != NULL; ++r_len) ;
+ cl = (*env)->FindClass (env, "java/lang/String");
+ jstr = (*env)->NewStringUTF (env, "");
+ jr = (*env)->NewObjectArray (env, r_len, cl, jstr);
+ for (i = 0; i < r_len; ++i) {
+ jstr = (*env)->NewStringUTF (env, r[i]);
+ (*env)->SetObjectArrayElement (env, jr, i, jstr);
+ free (r[i]);
+ }
+ free (r);
+ return jr;
+}
+
+JNIEXPORT jobjectArray JNICALL
+Java_com_redhat_et_libguestfs_GuestFS__1tail
+ (JNIEnv *env, jobject obj, jlong jg, jstring jpath)
+{
+ guestfs_h *g = (guestfs_h *) (long) jg;
+ jobjectArray jr;
+ int r_len;
+ jclass cl;
+ jstring jstr;
+ char **r;
+ const char *path;
+ int i;
+
+ path = (*env)->GetStringUTFChars (env, jpath, NULL);
+ r = guestfs_tail (g, path);
+ (*env)->ReleaseStringUTFChars (env, jpath, path);
+ if (r == NULL) {
+ throw_exception (env, guestfs_last_error (g));
+ return NULL;
+ }
+ for (r_len = 0; r[r_len] != NULL; ++r_len) ;
+ cl = (*env)->FindClass (env, "java/lang/String");
+ jstr = (*env)->NewStringUTF (env, "");
+ jr = (*env)->NewObjectArray (env, r_len, cl, jstr);
+ for (i = 0; i < r_len; ++i) {
+ jstr = (*env)->NewStringUTF (env, r[i]);
+ (*env)->SetObjectArrayElement (env, jr, i, jstr);
+ free (r[i]);
+ }
+ free (r);
+ return jr;
+}
+
+JNIEXPORT jobjectArray JNICALL
+Java_com_redhat_et_libguestfs_GuestFS__1tail_1n
+ (JNIEnv *env, jobject obj, jlong jg, jint jnrlines, jstring jpath)
+{
+ guestfs_h *g = (guestfs_h *) (long) jg;
+ jobjectArray jr;
+ int r_len;
+ jclass cl;
+ jstring jstr;
+ char **r;
+ int nrlines;
+ const char *path;
+ int i;
+
+ nrlines = jnrlines;
+ path = (*env)->GetStringUTFChars (env, jpath, NULL);
+ r = guestfs_tail_n (g, nrlines, path);
+ (*env)->ReleaseStringUTFChars (env, jpath, path);
+ if (r == NULL) {
+ throw_exception (env, guestfs_last_error (g));
+ return NULL;
+ }
+ for (r_len = 0; r[r_len] != NULL; ++r_len) ;
+ cl = (*env)->FindClass (env, "java/lang/String");
+ jstr = (*env)->NewStringUTF (env, "");
+ jr = (*env)->NewObjectArray (env, r_len, cl, jstr);
+ for (i = 0; i < r_len; ++i) {
+ jstr = (*env)->NewStringUTF (env, r[i]);
+ (*env)->SetObjectArrayElement (env, jr, i, jstr);
+ free (r[i]);
+ }
+ free (r);
+ return jr;
+}
+
external wc_l : t -> string -> int = "ocaml_guestfs_wc_l"
external wc_w : t -> string -> int = "ocaml_guestfs_wc_w"
external wc_c : t -> string -> int = "ocaml_guestfs_wc_c"
+external head : t -> string -> string array = "ocaml_guestfs_head"
+external head_n : t -> int -> string -> string array = "ocaml_guestfs_head_n"
+external tail : t -> string -> string array = "ocaml_guestfs_tail"
+external tail_n : t -> int -> string -> string array = "ocaml_guestfs_tail_n"
val wc_c : t -> string -> int
(** count characters in a file *)
+val head : t -> string -> string array
+(** return first 10 lines of a file *)
+
+val head_n : t -> int -> string -> string array
+(** return first N lines of a file *)
+
+val tail : t -> string -> string array
+(** return last 10 lines of a file *)
+
+val tail_n : t -> int -> string -> string array
+(** return last N lines of a file *)
+
}
CAMLprim value
-ocaml_guestfs_sfdisk_N (value gv, value devicev, value nv, value cylsv, value headsv, value sectorsv, value linev)
+ocaml_guestfs_sfdisk_N (value gv, value devicev, value partnumv, value cylsv, value headsv, value sectorsv, value linev)
{
- CAMLparam5 (gv, devicev, nv, cylsv, headsv);
+ CAMLparam5 (gv, devicev, partnumv, cylsv, headsv);
CAMLxparam2 (sectorsv, linev);
CAMLlocal1 (rv);
caml_failwith ("sfdisk_N: used handle after closing it");
const char *device = String_val (devicev);
- int n = Int_val (nv);
+ int partnum = Int_val (partnumv);
int cyls = Int_val (cylsv);
int heads = Int_val (headsv);
int sectors = Int_val (sectorsv);
int r;
caml_enter_blocking_section ();
- r = guestfs_sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ r = guestfs_sfdisk_N (g, device, partnum, cyls, heads, sectors, line);
caml_leave_blocking_section ();
if (r == -1)
ocaml_guestfs_raise_error (g, "sfdisk_N");
CAMLreturn (rv);
}
+CAMLprim value
+ocaml_guestfs_head (value gv, value pathv)
+{
+ CAMLparam2 (gv, pathv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("head: used handle after closing it");
+
+ const char *path = String_val (pathv);
+ int i;
+ char **r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_head (g, path);
+ caml_leave_blocking_section ();
+ if (r == NULL)
+ ocaml_guestfs_raise_error (g, "head");
+
+ rv = caml_copy_string_array ((const char **) r);
+ for (i = 0; r[i] != NULL; ++i) free (r[i]);
+ free (r);
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_head_n (value gv, value nrlinesv, value pathv)
+{
+ CAMLparam3 (gv, nrlinesv, pathv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("head_n: used handle after closing it");
+
+ int nrlines = Int_val (nrlinesv);
+ const char *path = String_val (pathv);
+ int i;
+ char **r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_head_n (g, nrlines, path);
+ caml_leave_blocking_section ();
+ if (r == NULL)
+ ocaml_guestfs_raise_error (g, "head_n");
+
+ rv = caml_copy_string_array ((const char **) r);
+ for (i = 0; r[i] != NULL; ++i) free (r[i]);
+ free (r);
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_tail (value gv, value pathv)
+{
+ CAMLparam2 (gv, pathv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("tail: used handle after closing it");
+
+ const char *path = String_val (pathv);
+ int i;
+ char **r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_tail (g, path);
+ caml_leave_blocking_section ();
+ if (r == NULL)
+ ocaml_guestfs_raise_error (g, "tail");
+
+ rv = caml_copy_string_array ((const char **) r);
+ for (i = 0; r[i] != NULL; ++i) free (r[i]);
+ free (r);
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_tail_n (value gv, value nrlinesv, value pathv)
+{
+ CAMLparam3 (gv, nrlinesv, pathv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("tail_n: used handle after closing it");
+
+ int nrlines = Int_val (nrlinesv);
+ const char *path = String_val (pathv);
+ int i;
+ char **r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_tail_n (g, nrlines, path);
+ caml_leave_blocking_section ();
+ if (r == NULL)
+ ocaml_guestfs_raise_error (g, "tail_n");
+
+ rv = caml_copy_string_array ((const char **) r);
+ for (i = 0; r[i] != NULL; ++i) free (r[i]);
+ free (r);
+ CAMLreturn (rv);
+}
+
croak ("pvresize: %s", guestfs_last_error (g));
void
-sfdisk_N (g, device, n, cyls, heads, sectors, line)
+sfdisk_N (g, device, partnum, cyls, heads, sectors, line)
guestfs_h *g;
char *device;
- int n;
+ int partnum;
int cyls;
int heads;
int sectors;
PREINIT:
int r;
PPCODE:
- r = guestfs_sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ r = guestfs_sfdisk_N (g, device, partnum, cyls, heads, sectors, line);
if (r == -1)
croak ("sfdisk_N: %s", guestfs_last_error (g));
OUTPUT:
RETVAL
+void
+head (g, path)
+ guestfs_h *g;
+ char *path;
+PREINIT:
+ char **lines;
+ int i, n;
+ PPCODE:
+ lines = guestfs_head (g, path);
+ if (lines == NULL)
+ croak ("head: %s", guestfs_last_error (g));
+ for (n = 0; lines[n] != NULL; ++n) /**/;
+ EXTEND (SP, n);
+ for (i = 0; i < n; ++i) {
+ PUSHs (sv_2mortal (newSVpv (lines[i], 0)));
+ free (lines[i]);
+ }
+ free (lines);
+
+void
+head_n (g, nrlines, path)
+ guestfs_h *g;
+ int nrlines;
+ char *path;
+PREINIT:
+ char **lines;
+ int i, n;
+ PPCODE:
+ lines = guestfs_head_n (g, nrlines, path);
+ if (lines == NULL)
+ croak ("head_n: %s", guestfs_last_error (g));
+ for (n = 0; lines[n] != NULL; ++n) /**/;
+ EXTEND (SP, n);
+ for (i = 0; i < n; ++i) {
+ PUSHs (sv_2mortal (newSVpv (lines[i], 0)));
+ free (lines[i]);
+ }
+ free (lines);
+
+void
+tail (g, path)
+ guestfs_h *g;
+ char *path;
+PREINIT:
+ char **lines;
+ int i, n;
+ PPCODE:
+ lines = guestfs_tail (g, path);
+ if (lines == NULL)
+ croak ("tail: %s", guestfs_last_error (g));
+ for (n = 0; lines[n] != NULL; ++n) /**/;
+ EXTEND (SP, n);
+ for (i = 0; i < n; ++i) {
+ PUSHs (sv_2mortal (newSVpv (lines[i], 0)));
+ free (lines[i]);
+ }
+ free (lines);
+
+void
+tail_n (g, nrlines, path)
+ guestfs_h *g;
+ int nrlines;
+ char *path;
+PREINIT:
+ char **lines;
+ int i, n;
+ PPCODE:
+ lines = guestfs_tail_n (g, nrlines, path);
+ if (lines == NULL)
+ croak ("tail_n: %s", guestfs_last_error (g));
+ for (n = 0; lines[n] != NULL; ++n) /**/;
+ EXTEND (SP, n);
+ for (i = 0; i < n; ++i) {
+ PUSHs (sv_2mortal (newSVpv (lines[i], 0)));
+ free (lines[i]);
+ }
+ free (lines);
+
This command installs GRUB (the Grand Unified Bootloader) on
C<device>, with the root directory being C<root>.
+=item @lines = $h->head ($path);
+
+This command returns up to the first 10 lines of a file as
+a list of strings.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
+=item @lines = $h->head_n ($nrlines, $path);
+
+If the parameter C<nrlines> is a positive number, this returns the first
+C<nrlines> lines of the file C<path>.
+
+If the parameter C<nrlines> is a negative number, this returns lines
+from the file C<path>, excluding the last C<nrlines> lines.
+
+If the parameter C<nrlines> is zero, this returns an empty list.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
=item $dump = $h->hexdump ($path);
This runs C<hexdump -C> on the given C<path>. The result is
B<This command is dangerous. Without careful use you
can easily destroy all your data>.
-=item $h->sfdisk_N ($device, $n, $cyls, $heads, $sectors, $line);
+=item $h->sfdisk_N ($device, $partnum, $cyls, $heads, $sectors, $line);
This runs L<sfdisk(8)> option to modify just the single
partition C<n> (note: C<n> counts from 1).
You should always call this if you have modified a disk image, before
closing the handle.
+=item @lines = $h->tail ($path);
+
+This command returns up to the last 10 lines of a file as
+a list of strings.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
+=item @lines = $h->tail_n ($nrlines, $path);
+
+If the parameter C<nrlines> is a positive number, this returns the last
+C<nrlines> lines of the file C<path>.
+
+If the parameter C<nrlines> is a negative number, this returns lines
+from the file C<path>, starting with the C<-nrlines>th line.
+
+If the parameter C<nrlines> is zero, this returns an empty list.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
=item $h->tar_in ($tarfile, $directory);
This command uploads and unpacks local file C<tarfile> (an
PyObject *py_r;
int r;
const char *device;
- int n;
+ int partnum;
int cyls;
int heads;
int sectors;
const char *line;
if (!PyArg_ParseTuple (args, (char *) "Osiiiis:guestfs_sfdisk_N",
- &py_g, &device, &n, &cyls, &heads, §ors, &line))
+ &py_g, &device, &partnum, &cyls, &heads, §ors, &line))
return NULL;
g = get_handle (py_g);
- r = guestfs_sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ r = guestfs_sfdisk_N (g, device, partnum, cyls, heads, sectors, line);
if (r == -1) {
PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
return NULL;
return py_r;
}
+static PyObject *
+py_guestfs_head (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ char **r;
+ const char *path;
+
+ if (!PyArg_ParseTuple (args, (char *) "Os:guestfs_head",
+ &py_g, &path))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_head (g, path);
+ if (r == NULL) {
+ PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
+ return NULL;
+ }
+
+ py_r = put_string_list (r);
+ free_strings (r);
+ return py_r;
+}
+
+static PyObject *
+py_guestfs_head_n (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ char **r;
+ int nrlines;
+ const char *path;
+
+ if (!PyArg_ParseTuple (args, (char *) "Ois:guestfs_head_n",
+ &py_g, &nrlines, &path))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_head_n (g, nrlines, path);
+ if (r == NULL) {
+ PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
+ return NULL;
+ }
+
+ py_r = put_string_list (r);
+ free_strings (r);
+ return py_r;
+}
+
+static PyObject *
+py_guestfs_tail (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ char **r;
+ const char *path;
+
+ if (!PyArg_ParseTuple (args, (char *) "Os:guestfs_tail",
+ &py_g, &path))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_tail (g, path);
+ if (r == NULL) {
+ PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
+ return NULL;
+ }
+
+ py_r = put_string_list (r);
+ free_strings (r);
+ return py_r;
+}
+
+static PyObject *
+py_guestfs_tail_n (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ char **r;
+ int nrlines;
+ const char *path;
+
+ if (!PyArg_ParseTuple (args, (char *) "Ois:guestfs_tail_n",
+ &py_g, &nrlines, &path))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_tail_n (g, nrlines, path);
+ if (r == NULL) {
+ PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
+ return NULL;
+ }
+
+ py_r = put_string_list (r);
+ free_strings (r);
+ return py_r;
+}
+
static PyMethodDef methods[] = {
{ (char *) "create", py_guestfs_create, METH_VARARGS, NULL },
{ (char *) "close", py_guestfs_close, METH_VARARGS, NULL },
{ (char *) "wc_l", py_guestfs_wc_l, METH_VARARGS, NULL },
{ (char *) "wc_w", py_guestfs_wc_w, METH_VARARGS, NULL },
{ (char *) "wc_c", py_guestfs_wc_c, METH_VARARGS, NULL },
+ { (char *) "head", py_guestfs_head, METH_VARARGS, NULL },
+ { (char *) "head_n", py_guestfs_head_n, METH_VARARGS, NULL },
+ { (char *) "tail", py_guestfs_tail, METH_VARARGS, NULL },
+ { (char *) "tail_n", py_guestfs_tail_n, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL }
};
"""
return libguestfsmod.pvresize (self._o, device)
- def sfdisk_N (self, device, n, cyls, heads, sectors, line):
+ def sfdisk_N (self, device, partnum, cyls, heads, sectors, line):
u"""This runs sfdisk(8) option to modify just the single
partition "n" (note: "n" counts from 1).
This command is dangerous. Without careful use you can
easily destroy all your data.
"""
- return libguestfsmod.sfdisk_N (self._o, device, n, cyls, heads, sectors, line)
+ return libguestfsmod.sfdisk_N (self._o, device, partnum, cyls, heads, sectors, line)
def sfdisk_l (self, device):
u"""This displays the partition table on "device", in the
"""
return libguestfsmod.wc_c (self._o, path)
+ def head (self, path):
+ u"""This command returns up to the first 10 lines of a file
+ as a list of strings.
+
+ This function returns a list of strings.
+
+ Because of the message protocol, there is a transfer
+ limit of somewhere between 2MB and 4MB. To transfer
+ large files you should use FTP.
+ """
+ return libguestfsmod.head (self._o, path)
+
+ def head_n (self, nrlines, path):
+ u"""If the parameter "nrlines" is a positive number, this
+ returns the first "nrlines" lines of the file "path".
+
+ If the parameter "nrlines" is a negative number, this
+ returns lines from the file "path", excluding the last
+ "nrlines" lines.
+
+ If the parameter "nrlines" is zero, this returns an
+ empty list.
+
+ This function returns a list of strings.
+
+ Because of the message protocol, there is a transfer
+ limit of somewhere between 2MB and 4MB. To transfer
+ large files you should use FTP.
+ """
+ return libguestfsmod.head_n (self._o, nrlines, path)
+
+ def tail (self, path):
+ u"""This command returns up to the last 10 lines of a file
+ as a list of strings.
+
+ This function returns a list of strings.
+
+ Because of the message protocol, there is a transfer
+ limit of somewhere between 2MB and 4MB. To transfer
+ large files you should use FTP.
+ """
+ return libguestfsmod.tail (self._o, path)
+
+ def tail_n (self, nrlines, path):
+ u"""If the parameter "nrlines" is a positive number, this
+ returns the last "nrlines" lines of the file "path".
+
+ If the parameter "nrlines" is a negative number, this
+ returns lines from the file "path", starting with the
+ "-nrlines"th line.
+
+ If the parameter "nrlines" is zero, this returns an
+ empty list.
+
+ This function returns a list of strings.
+
+ Because of the message protocol, there is a transfer
+ limit of somewhere between 2MB and 4MB. To transfer
+ large files you should use FTP.
+ """
+ return libguestfsmod.tail_n (self._o, nrlines, path)
+
return Qnil;
}
-static VALUE ruby_guestfs_sfdisk_N (VALUE gv, VALUE devicev, VALUE nv, VALUE cylsv, VALUE headsv, VALUE sectorsv, VALUE linev)
+static VALUE ruby_guestfs_sfdisk_N (VALUE gv, VALUE devicev, VALUE partnumv, VALUE cylsv, VALUE headsv, VALUE sectorsv, VALUE linev)
{
guestfs_h *g;
Data_Get_Struct (gv, guestfs_h, g);
if (!device)
rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
"device", "sfdisk_N");
- int n = NUM2INT (nv);
+ int partnum = NUM2INT (partnumv);
int cyls = NUM2INT (cylsv);
int heads = NUM2INT (headsv);
int sectors = NUM2INT (sectorsv);
int r;
- r = guestfs_sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ r = guestfs_sfdisk_N (g, device, partnum, cyls, heads, sectors, line);
if (r == -1)
rb_raise (e_Error, "%s", guestfs_last_error (g));
return INT2NUM (r);
}
+static VALUE ruby_guestfs_head (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "head");
+
+ Check_Type (pathv, T_STRING);
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "head");
+
+ char **r;
+
+ r = guestfs_head (g, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_head_n (VALUE gv, VALUE nrlinesv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "head_n");
+
+ int nrlines = NUM2INT (nrlinesv);
+ Check_Type (pathv, T_STRING);
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "head_n");
+
+ char **r;
+
+ r = guestfs_head_n (g, nrlines, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_tail (VALUE gv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "tail");
+
+ Check_Type (pathv, T_STRING);
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "tail");
+
+ char **r;
+
+ r = guestfs_tail (g, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_tail_n (VALUE gv, VALUE nrlinesv, VALUE pathv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "tail_n");
+
+ int nrlines = NUM2INT (nrlinesv);
+ Check_Type (pathv, T_STRING);
+ const char *path = StringValueCStr (pathv);
+ if (!path)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "path", "tail_n");
+
+ char **r;
+
+ r = guestfs_tail_n (g, nrlines, path);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ int i, len = 0;
+ for (i = 0; r[i] != NULL; ++i) len++;
+ VALUE rv = rb_ary_new2 (len);
+ for (i = 0; r[i] != NULL; ++i) {
+ rb_ary_push (rv, rb_str_new2 (r[i]));
+ free (r[i]);
+ }
+ free (r);
+ return rv;
+}
+
/* Initialize the module. */
void Init__guestfs ()
{
ruby_guestfs_wc_w, 1);
rb_define_method (c_guestfs, "wc_c",
ruby_guestfs_wc_c, 1);
+ rb_define_method (c_guestfs, "head",
+ ruby_guestfs_head, 1);
+ rb_define_method (c_guestfs, "head_n",
+ ruby_guestfs_head_n, 2);
+ rb_define_method (c_guestfs, "tail",
+ ruby_guestfs_tail, 1);
+ rb_define_method (c_guestfs, "tail_n",
+ ruby_guestfs_tail_n, 2);
}
int guestfs_sfdisk_N (guestfs_h *g,
const char *device,
- int n,
+ int partnum,
int cyls,
int heads,
int sectors,
memset (&ctx, 0, sizeof ctx);
args.device = (char *) device;
- args.n = n;
+ args.partnum = partnum;
args.cyls = cyls;
args.heads = heads;
args.sectors = sectors;
return ctx.ret.chars;
}
+struct head_ctx {
+ /* This flag is set by the callbacks, so we know we've done
+ * the callbacks as expected, and in the right sequence.
+ * 0 = not called, 1 = reply_cb called.
+ */
+ int cb_sequence;
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_head_ret ret;
+};
+
+static void head_reply_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ struct head_ctx *ctx = (struct head_ctx *) data;
+
+ /* This should definitely not happen. */
+ if (ctx->cb_sequence != 0) {
+ ctx->cb_sequence = 9999;
+ error (g, "%s: internal error: reply callback called twice", "guestfs_head");
+ return;
+ }
+
+ ml->main_loop_quit (ml, g);
+
+ if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
+ error (g, "%s: failed to parse reply header", "guestfs_head");
+ return;
+ }
+ if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
+ error (g, "%s: failed to parse reply error", "guestfs_head");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_head_ret (xdr, &ctx->ret)) {
+ error (g, "%s: failed to parse reply", "guestfs_head");
+ return;
+ }
+ done:
+ ctx->cb_sequence = 1;
+}
+
+char **guestfs_head (guestfs_h *g,
+ const char *path)
+{
+ struct guestfs_head_args args;
+ struct head_ctx ctx;
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ int serial;
+
+ if (check_state (g, "guestfs_head") == -1) return NULL;
+ guestfs_set_busy (g);
+
+ memset (&ctx, 0, sizeof ctx);
+
+ args.path = (char *) path;
+ serial = guestfs__send_sync (g, GUESTFS_PROC_HEAD,
+ (xdrproc_t) xdr_guestfs_head_args, (char *) &args);
+ if (serial == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs__switch_to_receiving (g);
+ ctx.cb_sequence = 0;
+ guestfs_set_reply_callback (g, head_reply_cb, &ctx);
+ (void) ml->main_loop_run (ml, g);
+ guestfs_set_reply_callback (g, NULL, NULL);
+ if (ctx.cb_sequence != 1) {
+ error (g, "%s reply failed, see earlier error messages", "guestfs_head");
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_HEAD, serial) == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", ctx.err.error_message);
+ free (ctx.err.error_message);
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs_end_busy (g);
+ /* caller will free this, but we need to add a NULL entry */
+ ctx.ret.lines.lines_val =
+ safe_realloc (g, ctx.ret.lines.lines_val,
+ sizeof (char *) * (ctx.ret.lines.lines_len + 1));
+ ctx.ret.lines.lines_val[ctx.ret.lines.lines_len] = NULL;
+ return ctx.ret.lines.lines_val;
+}
+
+struct head_n_ctx {
+ /* This flag is set by the callbacks, so we know we've done
+ * the callbacks as expected, and in the right sequence.
+ * 0 = not called, 1 = reply_cb called.
+ */
+ int cb_sequence;
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_head_n_ret ret;
+};
+
+static void head_n_reply_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ struct head_n_ctx *ctx = (struct head_n_ctx *) data;
+
+ /* This should definitely not happen. */
+ if (ctx->cb_sequence != 0) {
+ ctx->cb_sequence = 9999;
+ error (g, "%s: internal error: reply callback called twice", "guestfs_head_n");
+ return;
+ }
+
+ ml->main_loop_quit (ml, g);
+
+ if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
+ error (g, "%s: failed to parse reply header", "guestfs_head_n");
+ return;
+ }
+ if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
+ error (g, "%s: failed to parse reply error", "guestfs_head_n");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_head_n_ret (xdr, &ctx->ret)) {
+ error (g, "%s: failed to parse reply", "guestfs_head_n");
+ return;
+ }
+ done:
+ ctx->cb_sequence = 1;
+}
+
+char **guestfs_head_n (guestfs_h *g,
+ int nrlines,
+ const char *path)
+{
+ struct guestfs_head_n_args args;
+ struct head_n_ctx ctx;
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ int serial;
+
+ if (check_state (g, "guestfs_head_n") == -1) return NULL;
+ guestfs_set_busy (g);
+
+ memset (&ctx, 0, sizeof ctx);
+
+ args.nrlines = nrlines;
+ args.path = (char *) path;
+ serial = guestfs__send_sync (g, GUESTFS_PROC_HEAD_N,
+ (xdrproc_t) xdr_guestfs_head_n_args, (char *) &args);
+ if (serial == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs__switch_to_receiving (g);
+ ctx.cb_sequence = 0;
+ guestfs_set_reply_callback (g, head_n_reply_cb, &ctx);
+ (void) ml->main_loop_run (ml, g);
+ guestfs_set_reply_callback (g, NULL, NULL);
+ if (ctx.cb_sequence != 1) {
+ error (g, "%s reply failed, see earlier error messages", "guestfs_head_n");
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_HEAD_N, serial) == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", ctx.err.error_message);
+ free (ctx.err.error_message);
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs_end_busy (g);
+ /* caller will free this, but we need to add a NULL entry */
+ ctx.ret.lines.lines_val =
+ safe_realloc (g, ctx.ret.lines.lines_val,
+ sizeof (char *) * (ctx.ret.lines.lines_len + 1));
+ ctx.ret.lines.lines_val[ctx.ret.lines.lines_len] = NULL;
+ return ctx.ret.lines.lines_val;
+}
+
+struct tail_ctx {
+ /* This flag is set by the callbacks, so we know we've done
+ * the callbacks as expected, and in the right sequence.
+ * 0 = not called, 1 = reply_cb called.
+ */
+ int cb_sequence;
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_tail_ret ret;
+};
+
+static void tail_reply_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ struct tail_ctx *ctx = (struct tail_ctx *) data;
+
+ /* This should definitely not happen. */
+ if (ctx->cb_sequence != 0) {
+ ctx->cb_sequence = 9999;
+ error (g, "%s: internal error: reply callback called twice", "guestfs_tail");
+ return;
+ }
+
+ ml->main_loop_quit (ml, g);
+
+ if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
+ error (g, "%s: failed to parse reply header", "guestfs_tail");
+ return;
+ }
+ if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
+ error (g, "%s: failed to parse reply error", "guestfs_tail");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_tail_ret (xdr, &ctx->ret)) {
+ error (g, "%s: failed to parse reply", "guestfs_tail");
+ return;
+ }
+ done:
+ ctx->cb_sequence = 1;
+}
+
+char **guestfs_tail (guestfs_h *g,
+ const char *path)
+{
+ struct guestfs_tail_args args;
+ struct tail_ctx ctx;
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ int serial;
+
+ if (check_state (g, "guestfs_tail") == -1) return NULL;
+ guestfs_set_busy (g);
+
+ memset (&ctx, 0, sizeof ctx);
+
+ args.path = (char *) path;
+ serial = guestfs__send_sync (g, GUESTFS_PROC_TAIL,
+ (xdrproc_t) xdr_guestfs_tail_args, (char *) &args);
+ if (serial == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs__switch_to_receiving (g);
+ ctx.cb_sequence = 0;
+ guestfs_set_reply_callback (g, tail_reply_cb, &ctx);
+ (void) ml->main_loop_run (ml, g);
+ guestfs_set_reply_callback (g, NULL, NULL);
+ if (ctx.cb_sequence != 1) {
+ error (g, "%s reply failed, see earlier error messages", "guestfs_tail");
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TAIL, serial) == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", ctx.err.error_message);
+ free (ctx.err.error_message);
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs_end_busy (g);
+ /* caller will free this, but we need to add a NULL entry */
+ ctx.ret.lines.lines_val =
+ safe_realloc (g, ctx.ret.lines.lines_val,
+ sizeof (char *) * (ctx.ret.lines.lines_len + 1));
+ ctx.ret.lines.lines_val[ctx.ret.lines.lines_len] = NULL;
+ return ctx.ret.lines.lines_val;
+}
+
+struct tail_n_ctx {
+ /* This flag is set by the callbacks, so we know we've done
+ * the callbacks as expected, and in the right sequence.
+ * 0 = not called, 1 = reply_cb called.
+ */
+ int cb_sequence;
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_tail_n_ret ret;
+};
+
+static void tail_n_reply_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ struct tail_n_ctx *ctx = (struct tail_n_ctx *) data;
+
+ /* This should definitely not happen. */
+ if (ctx->cb_sequence != 0) {
+ ctx->cb_sequence = 9999;
+ error (g, "%s: internal error: reply callback called twice", "guestfs_tail_n");
+ return;
+ }
+
+ ml->main_loop_quit (ml, g);
+
+ if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
+ error (g, "%s: failed to parse reply header", "guestfs_tail_n");
+ return;
+ }
+ if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
+ error (g, "%s: failed to parse reply error", "guestfs_tail_n");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_tail_n_ret (xdr, &ctx->ret)) {
+ error (g, "%s: failed to parse reply", "guestfs_tail_n");
+ return;
+ }
+ done:
+ ctx->cb_sequence = 1;
+}
+
+char **guestfs_tail_n (guestfs_h *g,
+ int nrlines,
+ const char *path)
+{
+ struct guestfs_tail_n_args args;
+ struct tail_n_ctx ctx;
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ int serial;
+
+ if (check_state (g, "guestfs_tail_n") == -1) return NULL;
+ guestfs_set_busy (g);
+
+ memset (&ctx, 0, sizeof ctx);
+
+ args.nrlines = nrlines;
+ args.path = (char *) path;
+ serial = guestfs__send_sync (g, GUESTFS_PROC_TAIL_N,
+ (xdrproc_t) xdr_guestfs_tail_n_args, (char *) &args);
+ if (serial == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs__switch_to_receiving (g);
+ ctx.cb_sequence = 0;
+ guestfs_set_reply_callback (g, tail_n_reply_cb, &ctx);
+ (void) ml->main_loop_run (ml, g);
+ guestfs_set_reply_callback (g, NULL, NULL);
+ if (ctx.cb_sequence != 1) {
+ error (g, "%s reply failed, see earlier error messages", "guestfs_tail_n");
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TAIL_N, serial) == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", ctx.err.error_message);
+ free (ctx.err.error_message);
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs_end_busy (g);
+ /* caller will free this, but we need to add a NULL entry */
+ ctx.ret.lines.lines_val =
+ safe_realloc (g, ctx.ret.lines.lines_val,
+ sizeof (char *) * (ctx.ret.lines.lines_len + 1));
+ ctx.ret.lines.lines_val[ctx.ret.lines.lines_len] = NULL;
+ return ctx.ret.lines.lines_val;
+}
+
extern char *guestfs_hexdump (guestfs_h *handle, const char *path);
extern int guestfs_zerofree (guestfs_h *handle, const char *device);
extern int guestfs_pvresize (guestfs_h *handle, const char *device);
-extern int guestfs_sfdisk_N (guestfs_h *handle, const char *device, int n, int cyls, int heads, int sectors, const char *line);
+extern int guestfs_sfdisk_N (guestfs_h *handle, const char *device, int partnum, int cyls, int heads, int sectors, const char *line);
extern char *guestfs_sfdisk_l (guestfs_h *handle, const char *device);
extern char *guestfs_sfdisk_kernel_geometry (guestfs_h *handle, const char *device);
extern char *guestfs_sfdisk_disk_geometry (guestfs_h *handle, const char *device);
extern int guestfs_wc_l (guestfs_h *handle, const char *path);
extern int guestfs_wc_w (guestfs_h *handle, const char *path);
extern int guestfs_wc_c (guestfs_h *handle, const char *path);
+extern char **guestfs_head (guestfs_h *handle, const char *path);
+extern char **guestfs_head_n (guestfs_h *handle, int nrlines, const char *path);
+extern char **guestfs_tail (guestfs_h *handle, const char *path);
+extern char **guestfs_tail_n (guestfs_h *handle, int nrlines, const char *path);
return FALSE;
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
- if (!xdr_int (xdrs, &objp->n))
+ if (!xdr_int (xdrs, &objp->partnum))
return FALSE;
if (!xdr_int (xdrs, &objp->cyls))
return FALSE;
return FALSE;
} else {
- IXDR_PUT_LONG(buf, objp->n);
+ IXDR_PUT_LONG(buf, objp->partnum);
IXDR_PUT_LONG(buf, objp->cyls);
IXDR_PUT_LONG(buf, objp->heads);
IXDR_PUT_LONG(buf, objp->sectors);
return FALSE;
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
- if (!xdr_int (xdrs, &objp->n))
+ if (!xdr_int (xdrs, &objp->partnum))
return FALSE;
if (!xdr_int (xdrs, &objp->cyls))
return FALSE;
return FALSE;
} else {
- objp->n = IXDR_GET_LONG(buf);
+ objp->partnum = IXDR_GET_LONG(buf);
objp->cyls = IXDR_GET_LONG(buf);
objp->heads = IXDR_GET_LONG(buf);
objp->sectors = IXDR_GET_LONG(buf);
if (!xdr_string (xdrs, &objp->device, ~0))
return FALSE;
- if (!xdr_int (xdrs, &objp->n))
+ if (!xdr_int (xdrs, &objp->partnum))
return FALSE;
if (!xdr_int (xdrs, &objp->cyls))
return FALSE;
}
bool_t
+xdr_guestfs_head_args (XDR *xdrs, guestfs_head_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->path, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_head_ret (XDR *xdrs, guestfs_head_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_array (xdrs, (char **)&objp->lines.lines_val, (u_int *) &objp->lines.lines_len, ~0,
+ sizeof (str), (xdrproc_t) xdr_str))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_head_n_args (XDR *xdrs, guestfs_head_n_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_int (xdrs, &objp->nrlines))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->path, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_head_n_ret (XDR *xdrs, guestfs_head_n_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_array (xdrs, (char **)&objp->lines.lines_val, (u_int *) &objp->lines.lines_len, ~0,
+ sizeof (str), (xdrproc_t) xdr_str))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_tail_args (XDR *xdrs, guestfs_tail_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->path, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_tail_ret (XDR *xdrs, guestfs_tail_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_array (xdrs, (char **)&objp->lines.lines_val, (u_int *) &objp->lines.lines_len, ~0,
+ sizeof (str), (xdrproc_t) xdr_str))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_tail_n_args (XDR *xdrs, guestfs_tail_n_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_int (xdrs, &objp->nrlines))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->path, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_tail_n_ret (XDR *xdrs, guestfs_tail_n_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_array (xdrs, (char **)&objp->lines.lines_val, (u_int *) &objp->lines.lines_len, ~0,
+ sizeof (str), (xdrproc_t) xdr_str))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_guestfs_procedure (XDR *xdrs, guestfs_procedure *objp)
{
register int32_t *buf;
struct guestfs_sfdisk_N_args {
char *device;
- int n;
+ int partnum;
int cyls;
int heads;
int sectors;
};
typedef struct guestfs_wc_c_ret guestfs_wc_c_ret;
+struct guestfs_head_args {
+ char *path;
+};
+typedef struct guestfs_head_args guestfs_head_args;
+
+struct guestfs_head_ret {
+ struct {
+ u_int lines_len;
+ str *lines_val;
+ } lines;
+};
+typedef struct guestfs_head_ret guestfs_head_ret;
+
+struct guestfs_head_n_args {
+ int nrlines;
+ char *path;
+};
+typedef struct guestfs_head_n_args guestfs_head_n_args;
+
+struct guestfs_head_n_ret {
+ struct {
+ u_int lines_len;
+ str *lines_val;
+ } lines;
+};
+typedef struct guestfs_head_n_ret guestfs_head_n_ret;
+
+struct guestfs_tail_args {
+ char *path;
+};
+typedef struct guestfs_tail_args guestfs_tail_args;
+
+struct guestfs_tail_ret {
+ struct {
+ u_int lines_len;
+ str *lines_val;
+ } lines;
+};
+typedef struct guestfs_tail_ret guestfs_tail_ret;
+
+struct guestfs_tail_n_args {
+ int nrlines;
+ char *path;
+};
+typedef struct guestfs_tail_n_args guestfs_tail_n_args;
+
+struct guestfs_tail_n_ret {
+ struct {
+ u_int lines_len;
+ str *lines_val;
+ } lines;
+};
+typedef struct guestfs_tail_n_ret guestfs_tail_n_ret;
+
enum guestfs_procedure {
GUESTFS_PROC_MOUNT = 1,
GUESTFS_PROC_SYNC = 2,
GUESTFS_PROC_WC_L = 118,
GUESTFS_PROC_WC_W = 119,
GUESTFS_PROC_WC_C = 120,
- GUESTFS_PROC_NR_PROCS = 120 + 1,
+ GUESTFS_PROC_HEAD = 121,
+ GUESTFS_PROC_HEAD_N = 122,
+ GUESTFS_PROC_TAIL = 123,
+ GUESTFS_PROC_TAIL_N = 124,
+ GUESTFS_PROC_NR_PROCS = 124 + 1,
};
typedef enum guestfs_procedure guestfs_procedure;
#define GUESTFS_MESSAGE_MAX 4194304
extern bool_t xdr_guestfs_wc_w_ret (XDR *, guestfs_wc_w_ret*);
extern bool_t xdr_guestfs_wc_c_args (XDR *, guestfs_wc_c_args*);
extern bool_t xdr_guestfs_wc_c_ret (XDR *, guestfs_wc_c_ret*);
+extern bool_t xdr_guestfs_head_args (XDR *, guestfs_head_args*);
+extern bool_t xdr_guestfs_head_ret (XDR *, guestfs_head_ret*);
+extern bool_t xdr_guestfs_head_n_args (XDR *, guestfs_head_n_args*);
+extern bool_t xdr_guestfs_head_n_ret (XDR *, guestfs_head_n_ret*);
+extern bool_t xdr_guestfs_tail_args (XDR *, guestfs_tail_args*);
+extern bool_t xdr_guestfs_tail_ret (XDR *, guestfs_tail_ret*);
+extern bool_t xdr_guestfs_tail_n_args (XDR *, guestfs_tail_n_args*);
+extern bool_t xdr_guestfs_tail_n_ret (XDR *, guestfs_tail_n_ret*);
extern bool_t xdr_guestfs_procedure (XDR *, guestfs_procedure*);
extern bool_t xdr_guestfs_message_direction (XDR *, guestfs_message_direction*);
extern bool_t xdr_guestfs_message_status (XDR *, guestfs_message_status*);
extern bool_t xdr_guestfs_wc_w_ret ();
extern bool_t xdr_guestfs_wc_c_args ();
extern bool_t xdr_guestfs_wc_c_ret ();
+extern bool_t xdr_guestfs_head_args ();
+extern bool_t xdr_guestfs_head_ret ();
+extern bool_t xdr_guestfs_head_n_args ();
+extern bool_t xdr_guestfs_head_n_ret ();
+extern bool_t xdr_guestfs_tail_args ();
+extern bool_t xdr_guestfs_tail_ret ();
+extern bool_t xdr_guestfs_tail_n_args ();
+extern bool_t xdr_guestfs_tail_n_ret ();
extern bool_t xdr_guestfs_procedure ();
extern bool_t xdr_guestfs_message_direction ();
extern bool_t xdr_guestfs_message_status ();
struct guestfs_sfdisk_N_args {
string device<>;
- int n;
+ int partnum;
int cyls;
int heads;
int sectors;
int chars;
};
+struct guestfs_head_args {
+ string path<>;
+};
+
+struct guestfs_head_ret {
+ str lines<>;
+};
+
+struct guestfs_head_n_args {
+ int nrlines;
+ string path<>;
+};
+
+struct guestfs_head_n_ret {
+ str lines<>;
+};
+
+struct guestfs_tail_args {
+ string path<>;
+};
+
+struct guestfs_tail_ret {
+ str lines<>;
+};
+
+struct guestfs_tail_n_args {
+ int nrlines;
+ string path<>;
+};
+
+struct guestfs_tail_n_ret {
+ str lines<>;
+};
+
enum guestfs_procedure {
GUESTFS_PROC_MOUNT = 1,
GUESTFS_PROC_SYNC = 2,
GUESTFS_PROC_WC_L = 118,
GUESTFS_PROC_WC_W = 119,
GUESTFS_PROC_WC_C = 120,
+ GUESTFS_PROC_HEAD = 121,
+ GUESTFS_PROC_HEAD_N = 122,
+ GUESTFS_PROC_TAIL = 123,
+ GUESTFS_PROC_TAIL_N = 124,
GUESTFS_PROC_NR_PROCS
};