]> git.saurik.com Git - apple/hfs.git/blob - tests/cases/test-getattrlist.c
hfs-556.100.11.tar.gz
[apple/hfs.git] / tests / cases / test-getattrlist.c
1 //
2 // test-getattrlist.c
3 // hfs
4 //
5 // Created by Chris Suter on 8/21/15.
6 //
7 //
8
9 #import <TargetConditionals.h>
10 #include <fcntl.h>
11 #include <sys/attr.h>
12 #include <unistd.h>
13 #include <sys/mount.h>
14 #include <sys/kauth.h>
15 #include <sys/param.h>
16
17 #include "hfs-tests.h"
18 #include "test-utils.h"
19 #include "disk-image.h"
20
21
22
23 TEST(getattrlist)
24
25 #define TEST_FILE_NAME "getattrlist-test.file"
26
27 int run_getattrlist(__unused test_ctx_t *ctx)
28 {
29 disk_image_t *di = NULL;
30 const char *tstdir;
31 bool hfs_root = true; //true until proven otherwise.
32
33 struct statfs sfs;
34 assert(statfs("/tmp", &sfs) == 0);
35 if (strcmp(sfs.f_fstypename, "hfs")) {
36 hfs_root = false;
37 di = disk_image_get();
38 tstdir = di->mount_point;
39 } else {
40 tstdir = "/tmp";
41 }
42
43 char *file;
44 asprintf(&file, "%s/getattrlist-test.file", tstdir);
45
46 unlink(file);
47 int fd = open_dprotected_np(file, O_RDWR | O_CREAT, 3, 0, 0666);
48
49 assert_with_errno(fd >= 0);
50
51 struct attrlist al = {
52 .bitmapcount = ATTR_BIT_MAP_COUNT,
53 .commonattr = ATTR_CMN_NAME | ATTR_CMN_DEVID | ATTR_CMN_FSID
54 | ATTR_CMN_OBJTYPE | ATTR_CMN_OBJTAG | ATTR_CMN_OBJID
55 | ATTR_CMN_OBJPERMANENTID | ATTR_CMN_PAROBJID | ATTR_CMN_SCRIPT
56 | ATTR_CMN_CRTIME | ATTR_CMN_MODTIME | ATTR_CMN_CHGTIME
57 | ATTR_CMN_ACCTIME | ATTR_CMN_BKUPTIME | ATTR_CMN_FNDRINFO
58 | ATTR_CMN_OWNERID | ATTR_CMN_GRPID | ATTR_CMN_ACCESSMASK
59 | ATTR_CMN_FLAGS | ATTR_CMN_GEN_COUNT | ATTR_CMN_DOCUMENT_ID
60 | ATTR_CMN_USERACCESS | ATTR_CMN_EXTENDED_SECURITY
61 | ATTR_CMN_UUID | ATTR_CMN_GRPUUID | ATTR_CMN_FILEID
62 | ATTR_CMN_PARENTID | ATTR_CMN_FULLPATH | ATTR_CMN_ADDEDTIME
63 | ATTR_CMN_DATA_PROTECT_FLAGS | ATTR_CMN_RETURNED_ATTRS,
64 };
65
66 #pragma pack(push, 4)
67 struct {
68 uint32_t len;
69 attribute_set_t returned_attrs;
70 struct attrreference name;
71 dev_t devid;
72 fsid_t fsid;
73 fsobj_type_t obj_type;
74 fsobj_tag_t obj_tag;
75 fsobj_id_t obj_id;
76 fsobj_id_t obj_perm_id;
77 fsobj_id_t par_obj_id;
78 text_encoding_t encoding;
79 struct timespec cr_time, mod_time, chg_time, acc_time, backup_time;
80 uint8_t finder_info[32];
81 uid_t owner;
82 gid_t group;
83 uint32_t access_mask;
84 uint32_t flags;
85 uint32_t gen_count;
86 uint32_t doc_id;
87 uint32_t access;
88 struct attrreference ext_security;
89 guid_t guid;
90 guid_t grp_uuid;
91 uint64_t file_id;
92 uint64_t parent_id;
93 struct attrreference full_path;
94 struct timespec added_time;
95 uint32_t protection_class;
96 uint8_t extra[1024];
97 } attrs;
98 #pragma pack(pop)
99
100 assert_no_err(fgetattrlist(fd, &al, &attrs, sizeof(attrs),
101 FSOPT_ATTR_CMN_EXTENDED | FSOPT_PACK_INVAL_ATTRS));
102
103 uint32_t expected = al.commonattr ^ ATTR_CMN_EXTENDED_SECURITY;
104
105 #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
106 if (hfs_root == true) {
107 assert(attrs.protection_class == 3);
108 }
109 #else
110 expected ^= ATTR_CMN_DATA_PROTECT_FLAGS;
111 assert(attrs.protection_class == 0);
112 #endif
113
114 assert_equal_int(attrs.returned_attrs.commonattr, expected);
115
116 // Just check a few things, not everything...
117
118 assert(!strcmp((char *)&attrs.name + attrs.name.attr_dataoffset,
119 TEST_FILE_NAME));
120 assert(strlen(TEST_FILE_NAME) + 1 == attrs.name.attr_length);
121
122 char path[PATH_MAX];
123 assert(!strcmp((char *)&attrs.full_path + attrs.full_path.attr_dataoffset,
124 realpath(file, path)));
125 assert(strlen(path) + 1 == attrs.full_path.attr_length);
126
127 time_t t = time(NULL);
128
129 assert(attrs.cr_time.tv_sec > t - 5);
130 assert(attrs.mod_time.tv_sec > t - 5);
131 assert(attrs.chg_time.tv_sec > t - 5);
132 assert(attrs.acc_time.tv_sec > t - 5);
133 assert(attrs.backup_time.tv_sec == 0);
134 assert(attrs.added_time.tv_sec > t - 5);
135
136 if (hfs_root) {
137 struct statfs sfs2;
138 assert(statfs("/bin", &sfs2) == 0);
139 assert(strcmp(sfs2.f_fstypename, "hfs") == 0);
140
141 // Check a file on the system partition (this only valid if root == hfs)
142 assert_no_err(getattrlist("/bin/sh", &al, &attrs, sizeof(attrs),
143 FSOPT_ATTR_CMN_EXTENDED | FSOPT_PACK_INVAL_ATTRS));
144
145 assert(attrs.returned_attrs.commonattr == expected);
146 assert(attrs.protection_class == 0);
147
148 assert(!strcmp((char *)&attrs.name + attrs.name.attr_dataoffset, "sh"));
149 assert(attrs.name.attr_length == 3);
150
151 assert(!strcmp((char *)&attrs.full_path + attrs.full_path.attr_dataoffset,
152 "/bin/sh"));
153 assert(attrs.full_path.attr_length == 8);
154 }
155
156 assert_no_err(close(fd));
157 assert_no_err(unlink(file));
158 free(file);
159
160 return 0;
161 }