]> git.saurik.com Git - apple/hfs.git/blob - tests/cases/test-cas-bsdflags.c
hfs-556.100.11.tar.gz
[apple/hfs.git] / tests / cases / test-cas-bsdflags.c
1 #include <unistd.h>
2 #include <errno.h>
3 #include <fcntl.h>
4 #include <stdio.h>
5 #include <sys/mman.h>
6 #include <string.h>
7 #include <sys/attr.h>
8 #include <sys/types.h>
9 #include <sys/sysctl.h>
10 #include <sys/stat.h>
11 #include <sys/xattr.h>
12 #include <sys/mount.h>
13 #include <sys/param.h>
14
15 #include <System/sys/fsctl.h>
16
17 #include "hfs-tests.h"
18 #include "test-utils.h"
19 #include "disk-image.h"
20 #include "systemx.h"
21
22 #define AFSCUTIL "/usr/local/bin/afscutil"
23
24 TEST(cas_bsdflags)
25
26 static bool
27 cas_bsd_flags(int fd, uint32_t expected_flags, uint32_t new_flags, int expected_error)
28 {
29 struct fsioc_cas_bsdflags cas;
30
31 cas.expected_flags = expected_flags;
32 cas.new_flags = new_flags;
33 cas.actual_flags = ~0; /* poison */
34
35 if (expected_error != 0) {
36 // no assert_call_fail() in test_hfs
37 assert(ffsctl(fd, FSIOC_CAS_BSDFLAGS, &cas, 0) == -1);
38 assert(errno == EPERM);
39 return true; // as expected - flags were not changed
40 } else {
41 assert_no_err(ffsctl(fd, FSIOC_CAS_BSDFLAGS, &cas, 0));
42 }
43
44 return (cas.expected_flags == cas.actual_flags);
45 }
46
47 static void
48 write_compressible_data(int fd)
49 {
50 // adapted from test_clonefile in apfs
51 char dbuf[4096];
52
53 // write some easily compressable data
54 memset(dbuf + 0*(sizeof(dbuf)/4), 'A', sizeof(dbuf)/4);
55 memset(dbuf + 1*(sizeof(dbuf)/4), 'B', sizeof(dbuf)/4);
56 memset(dbuf + 2*(sizeof(dbuf)/4), 'C', sizeof(dbuf)/4);
57 memset(dbuf + 3*(sizeof(dbuf)/4), 'D', sizeof(dbuf)/4);
58 for (int idx = 0; idx < 32; idx++) {
59 check_io(write(fd, dbuf, sizeof(dbuf)), sizeof(dbuf));
60 }
61 }
62
63 int run_cas_bsdflags(__unused test_ctx_t *ctx)
64 {
65 disk_image_t *di = disk_image_get();
66 struct stat sb;
67 int fd;
68
69 char *file;
70 asprintf(&file, "%s/cas_bsdflags.data", di->mount_point);
71
72 assert_with_errno((fd = open(file,
73 O_CREAT | O_RDWR | O_TRUNC, 0666)) >= 0);
74
75 assert_no_err(fchflags(fd, UF_HIDDEN));
76 assert_no_err(fstat(fd, &sb));
77 assert_equal_int(sb.st_flags, UF_HIDDEN);
78
79 assert(cas_bsd_flags(fd, 0, UF_NODUMP, 0) == false);
80 assert_no_err(fstat(fd, &sb));
81 assert_equal_int(sb.st_flags, UF_HIDDEN);
82
83 assert(cas_bsd_flags(fd, UF_HIDDEN, UF_NODUMP, 0) == true);
84 assert_no_err(fstat(fd, &sb));
85 assert_equal_int(sb.st_flags, UF_NODUMP);
86
87 assert(cas_bsd_flags(fd, UF_NODUMP, 0, 0) == true);
88 assert_no_err(fstat(fd, &sb));
89 assert_equal_int(sb.st_flags, 0);
90
91 // Add some data to our (non-compressed) file,
92 // mark it with UF_COMPRESSED,
93 // and check that UF_COMPRESSED is *not* set -
94 // as there is no decmpfs xattr present.
95 check_io(write(fd, "J", 1), 1);
96 assert_no_err(fstat(fd, &sb));
97 assert(sb.st_size > 0);
98
99 assert(cas_bsd_flags(fd, 0, UF_COMPRESSED, EPERM) == true);
100 assert_no_err(fstat(fd, &sb));
101 assert_equal_int(sb.st_flags, 0);
102
103 // Now, add some compressible data to the file and compress it using afscutil.
104 write_compressible_data(fd);
105 assert(!systemx(AFSCUTIL, "-c", file, NULL));
106 assert_no_err(fstat(fd, &sb));
107 assert_equal_int(sb.st_flags, UF_COMPRESSED);
108
109 // Now, remove UF_COMPRESSED from our file and
110 // check that the file is 0-length.
111 assert(cas_bsd_flags(fd, UF_COMPRESSED, 0, 0) == true);
112 assert_no_err(fstat(fd, &sb));
113 assert_equal_ll(sb.st_size, 0);
114
115 close(fd);
116 assert_no_err(unlink(file));
117 free(file);
118
119 return 0;
120 }
121