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