22 /* |
22 /* |
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. |
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. |
24 * Use is subject to license terms. |
24 * Use is subject to license terms. |
25 */ |
25 */ |
26 |
26 |
|
27 /* |
|
28 * Unfortunately, the behavior this module has inherited is not one |
|
29 * of "get me information about file X or directory Y", but "tell me |
|
30 * what calling 'new File(X)' would do in Java". This includes |
|
31 * nonsense like manufacturing correct fake data for nonexistent |
|
32 * files. |
|
33 * |
|
34 * This sorely needs to be ripped out and replaced with a sane |
|
35 * interface. |
|
36 */ |
|
37 |
27 #include <sys/stat.h> |
38 #include <sys/stat.h> |
28 #include <sys/types.h> |
39 #include <sys/types.h> |
29 #include <string.h> |
40 #include <string.h> |
30 #include <stdio.h> |
41 #include <stdio.h> |
31 #include <stdlib.h> |
42 #include <stdlib.h> |
32 #include <unistd.h> |
43 #include <unistd.h> |
33 #include <time.h> |
44 #include <time.h> |
34 #include <dirent.h> |
45 #include <dirent.h> |
35 #include <libgen.h> |
46 #include <libgen.h> |
|
47 #include <limits.h> |
36 |
48 |
37 #include "rad_adr.h" |
49 #include "rad_adr.h" |
38 #include "rad_object.h" |
50 #include "rad_object.h" |
39 #include "rad_modapi.h" |
51 #include "rad_modapi.h" |
40 |
52 |
41 #include "api_file.h" |
53 #include "api_file.h" |
42 |
54 |
43 static data_t * |
55 static data_t * |
44 read_file(const char *path) |
56 empty_file(data_t *data, const char *apath, const char *cpath) |
45 { |
57 { |
46 char foo[1000]; |
58 struct_set(data, "absolutePath", data_new_string(apath, lt_copy)); |
47 char bar[1000] = { 0 }; |
59 struct_set(data, "canonicalPath", data_new_string(cpath, lt_copy)); |
|
60 struct_set(data, "canonical", data_new_boolean(B_TRUE)); |
|
61 struct_set(data, "baseName", data_new_string("", lt_copy)); |
|
62 struct_set(data, "exists", data_new_boolean(B_FALSE)); |
|
63 struct_set(data, "readable", data_new_boolean(B_FALSE)); |
|
64 struct_set(data, "writable", data_new_boolean(B_FALSE)); |
|
65 struct_set(data, "hidden", data_new_boolean(B_FALSE)); |
|
66 struct_set(data, "directory", data_new_boolean(B_FALSE)); |
|
67 struct_set(data, "file", data_new_boolean(B_FALSE)); |
|
68 struct_set(data, "lastModified", data_new_time(0)); |
|
69 struct_set(data, "length", data_new_long(0)); |
|
70 struct_set(data, "freeSpace", data_new_long(0)); |
|
71 struct_set(data, "totalSpace", data_new_long(0)); |
|
72 struct_set(data, "usableSpace", data_new_long(0)); |
|
73 return (data_purify(data)); |
|
74 } |
48 |
75 |
49 data_t *root = data_new_struct(&t__FileSnapshot); |
76 static data_t * |
50 struct_set(root, "path", data_new_string(path, lt_copy)); |
77 read_file(const char *path, const char *file) |
|
78 { |
|
79 struct stat64 st; |
|
80 char apath[PATH_MAX] = ""; |
|
81 char cpath[PATH_MAX] = ""; |
|
82 const char *name = file != NULL ? file : path; |
|
83 |
|
84 data_t *data = data_new_struct(&t__FileSnapshot); |
|
85 struct_set(data, "path", data_new_string(name, lt_copy)); |
|
86 struct_set(data, "absolute", data_new_boolean(name[0] == '/')); |
51 |
87 |
52 if (path[0] != '/') { |
88 if (path[0] != '/') { |
53 getcwd(foo, 1000); |
89 if (getcwd(apath, PATH_MAX) == NULL) { |
54 strlcat(foo, "/", 1000); |
90 data_free(data); |
55 strlcat(foo, path, 1000); |
91 return (NULL); |
|
92 } |
|
93 if (apath[1] != '\0') |
|
94 strlcat(apath, "/", PATH_MAX); |
|
95 strlcat(apath, path, PATH_MAX); |
56 } else { |
96 } else { |
57 strlcpy(foo, path, 1000); |
97 strlcpy(apath, path, PATH_MAX); |
58 } |
|
59 struct_set(root, "absolutePath", data_new_string(foo, lt_copy)); |
|
60 struct_set(root, "baseName", data_new_string(basename(foo), lt_copy)); |
|
61 |
|
62 resolvepath(foo, bar, 1000); |
|
63 struct_set(root, "canonicalPath", data_new_string(bar, lt_copy)); |
|
64 struct_set(root, "absolute", data_new_boolean(B_TRUE)); |
|
65 struct_set(root, "canonical", data_new_boolean(strcmp(foo, bar) == 0)); |
|
66 struct_set(root, "exists", data_new_boolean(B_TRUE)); |
|
67 struct_set(root, "readable", data_new_boolean(access(path, R_OK) == 0)); |
|
68 struct_set(root, "writable", data_new_boolean(access(path, W_OK) == 0)); |
|
69 struct_set(root, "directory", data_new_boolean(B_TRUE)); |
|
70 struct_set(root, "file", data_new_boolean(B_FALSE)); |
|
71 struct_set(root, "hidden", data_new_boolean(B_FALSE)); |
|
72 struct stat st; |
|
73 if (stat(path, &st) == -1) { |
|
74 data_free(root); |
|
75 return (NULL); |
|
76 } |
98 } |
77 |
99 |
78 struct_set(root, "lastModified", data_new_time(st.st_mtime)); |
100 if (resolvepath(apath, cpath, PATH_MAX) == -1 || |
|
101 stat64(path, &st) == -1) |
|
102 return (empty_file(data, apath, apath)); |
|
103 |
|
104 struct_set(data, "absolutePath", data_new_string(apath, lt_copy)); |
|
105 struct_set(data, "canonicalPath", data_new_string(cpath, lt_copy)); |
|
106 struct_set(data, "canonical", |
|
107 data_new_boolean(strcmp(apath, cpath) == 0)); |
|
108 struct_set(data, "baseName", data_new_string(basename(apath), lt_copy)); |
|
109 struct_set(data, "exists", data_new_boolean(B_TRUE)); |
|
110 struct_set(data, "readable", data_new_boolean(access(path, R_OK) == 0)); |
|
111 struct_set(data, "writable", data_new_boolean(access(path, W_OK) == 0)); |
|
112 struct_set(data, "hidden", data_new_boolean(B_FALSE)); |
|
113 struct_set(data, "directory", data_new_boolean(S_ISDIR(st.st_mode))); |
|
114 struct_set(data, "file", data_new_boolean(S_ISREG(st.st_mode))); |
|
115 struct_set(data, "lastModified", data_new_time(st.st_mtime)); |
79 /* XXX: 64-bitify */ |
116 /* XXX: 64-bitify */ |
80 struct_set(root, "length", data_new_integer(st.st_size)); |
117 struct_set(data, "length", data_new_long(st.st_size)); |
81 struct_set(root, "freeSpace", data_new_integer(0)); |
118 struct_set(data, "freeSpace", data_new_long(0)); |
82 struct_set(root, "totalSpace", data_new_integer(0)); |
119 struct_set(data, "totalSpace", data_new_long(0)); |
83 struct_set(root, "usableSpace", data_new_integer(0)); |
120 struct_set(data, "usableSpace", data_new_long(0)); |
84 return (root); |
121 return (data_purify(data)); |
85 } |
122 } |
86 |
123 |
87 /* ARGSUSED */ |
124 /* ARGSUSED */ |
88 conerr_t |
125 conerr_t |
89 api_fileBrowser_read_Roots(struct instance *inst, struct attribute *attr, |
126 api_fileBrowser_read_Roots(struct instance *inst, struct attribute *attr, |
90 data_t **data, data_t **error) |
127 data_t **data, data_t **error) |
91 { |
128 { |
92 data_t *result = data_new_array(&t_array__FileSnapshot, 1); |
129 data_t *result = data_new_array(&t_array__FileSnapshot, 1); |
93 array_add(result, read_file("/")); |
130 array_add(result, read_file("/", NULL)); |
94 *data = result; |
131 *data = data_purify(result); |
95 return (ce_ok); |
132 return (ce_ok); |
96 } |
133 } |
97 |
134 |
98 /* ARGSUSED */ |
135 /* ARGSUSED */ |
99 conerr_t |
136 conerr_t |
100 api_fileBrowser_invoke_getFile(struct instance *inst, struct method *meth, |
137 api_fileBrowser_invoke_getFile(struct instance *inst, struct method *meth, |
101 data_t **ret, data_t **args, int count, data_t **error) |
138 data_t **ret, data_t **args, int count, data_t **error) |
102 { |
139 { |
103 *ret = read_file(args[0]->d_data.string); |
140 *ret = read_file(args[0]->d_data.string, NULL); |
104 return (ce_ok); |
141 return (ce_ok); |
105 } |
142 } |
106 |
143 |
107 /* ARGSUSED */ |
144 /* ARGSUSED */ |
108 conerr_t |
145 conerr_t |