usr/src/cmd/rad/mod/files/mod_files.c
changeset 401 fc1223edbd8d
parent 391 71abce159a62
child 500 d134d555588f
equal deleted inserted replaced
400:6eb404d32758 401:fc1223edbd8d
    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
   117 	if (d == NULL)
   154 	if (d == NULL)
   118 		return (ce_object);
   155 		return (ce_object);
   119 
   156 
   120 	result = data_new_array(&t_array__FileSnapshot, 1);
   157 	result = data_new_array(&t_array__FileSnapshot, 1);
   121 	while ((ent = readdir(d)) != NULL) {
   158 	while ((ent = readdir(d)) != NULL) {
   122 		char buf[1000];
   159 		char buf[PATH_MAX];
   123 		if (strcmp(ent->d_name, ".") == 0 ||
   160 		if (strcmp(ent->d_name, ".") == 0 ||
   124 		    strcmp(ent->d_name, "..") == 0)
   161 		    strcmp(ent->d_name, "..") == 0)
   125 			continue;
   162 			continue;
   126 		int len = strlen(path);
   163 		int len = strlen(path);
   127 		while (len > 0 && path[len - 1] == '/')
   164 		while (len > 0 && path[len - 1] == '/')
   128 			len--;
   165 			len--;
   129 		snprintf(buf, 1000, "%.*s/%s", len, path, ent->d_name);
   166 		snprintf(buf, PATH_MAX, "%.*s/%s", len, path, ent->d_name);
   130 		data_t *file = read_file(buf);
   167 		data_t *file = read_file(buf, NULL);
   131 		if (file != NULL)
   168 		if (file != NULL)
   132 			array_add(result, file);
   169 			array_add(result, file);
   133 	}
   170 	}
   134 	closedir(d);
   171 	(void) closedir(d);
   135 	*ret = result;
   172 	*ret = data_purify(result);
   136 
   173 
   137 	return (ce_ok);
   174 	return (ce_ok);
   138 }
   175 }
   139 
   176 
   140 static rad_modinfo_t modinfo = { "files", "File Browser module" };
   177 static rad_modinfo_t modinfo = { "files", "File Browser module" };