components/visual-panels/core/src/cmd/rad/mod/files/mod_files.c
branchs11-update
changeset 3038 1a97ff5e830d
parent 3037 ef46824e0e76
child 3039 bf667aad6d27
equal deleted inserted replaced
3037:ef46824e0e76 3038:1a97ff5e830d
     1 /*
       
     2  * CDDL HEADER START
       
     3  *
       
     4  * The contents of this file are subject to the terms of the
       
     5  * Common Development and Distribution License (the "License").
       
     6  * You may not use this file except in compliance with the License.
       
     7  *
       
     8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
       
     9  * or http://www.opensolaris.org/os/licensing.
       
    10  * See the License for the specific language governing permissions
       
    11  * and limitations under the License.
       
    12  *
       
    13  * When distributing Covered Code, include this CDDL HEADER in each
       
    14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
       
    15  * If applicable, add the following below this CDDL HEADER, with the
       
    16  * fields enclosed by brackets "[]" replaced with your own identifying
       
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
       
    18  *
       
    19  * CDDL HEADER END
       
    20  */
       
    21 
       
    22 /*
       
    23  * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
       
    24  */
       
    25 
       
    26 /*
       
    27  * Unfortunately, the behavior this module has inherited is not one
       
    28  * of "get me information about file X or directory Y", but "tell me
       
    29  * what calling 'new File(X)' would do in Java".  This includes
       
    30  * nonsense like manufacturing correct fake data for nonexistent
       
    31  * files.
       
    32  *
       
    33  * This sorely needs to be ripped out and replaced with a sane
       
    34  * api.
       
    35  */
       
    36 
       
    37 #include <sys/stat.h>
       
    38 #include <sys/types.h>
       
    39 #include <string.h>
       
    40 #include <stdio.h>
       
    41 #include <stdlib.h>
       
    42 #include <unistd.h>
       
    43 #include <time.h>
       
    44 #include <dirent.h>
       
    45 #include <libgen.h>
       
    46 #include <limits.h>
       
    47 
       
    48 #include <rad/adr.h>
       
    49 #include <rad/rad_modapi.h>
       
    50 
       
    51 #include "api_file.h"
       
    52 
       
    53 static adr_data_t *
       
    54 empty_file(adr_data_t *data, const char *apath, const char *cpath)
       
    55 {
       
    56 	adr_struct_set(data, "absolutePath",
       
    57 	    adr_data_new_string(apath, LT_COPY));
       
    58 	adr_struct_set(data, "canonicalPath",
       
    59 	    adr_data_new_string(cpath, LT_COPY));
       
    60 	adr_struct_set(data, "canonical", adr_data_new_boolean(B_TRUE));
       
    61 	adr_struct_set(data, "baseName", adr_data_new_string("", LT_COPY));
       
    62 	adr_struct_set(data, "exists", adr_data_new_boolean(B_FALSE));
       
    63 	adr_struct_set(data, "readable", adr_data_new_boolean(B_FALSE));
       
    64 	adr_struct_set(data, "writable", adr_data_new_boolean(B_FALSE));
       
    65 	adr_struct_set(data, "hidden", adr_data_new_boolean(B_FALSE));
       
    66 	adr_struct_set(data, "directory", adr_data_new_boolean(B_FALSE));
       
    67 	adr_struct_set(data, "file", adr_data_new_boolean(B_FALSE));
       
    68 	adr_struct_set(data, "lastModified", adr_data_new_time(0, 0));
       
    69 	adr_struct_set(data, "length", adr_data_new_long(0));
       
    70 	adr_struct_set(data, "freeSpace", adr_data_new_long(0));
       
    71 	adr_struct_set(data, "totalSpace", adr_data_new_long(0));
       
    72 	adr_struct_set(data, "usableSpace", adr_data_new_long(0));
       
    73 	return (adr_data_purify(data));
       
    74 }
       
    75 
       
    76 static adr_data_t *
       
    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 	adr_data_t *data = adr_data_new_struct(&t__FileSnapshot);
       
    85 	adr_struct_set(data, "path", adr_data_new_string(name, LT_COPY));
       
    86 	adr_struct_set(data, "absolute", adr_data_new_boolean(name[0] == '/'));
       
    87 
       
    88 	if (path[0] != '/') {
       
    89 		if (getcwd(apath, PATH_MAX) == NULL) {
       
    90 			adr_data_free(data);
       
    91 			return (NULL);
       
    92 		}
       
    93 		if (apath[1] != '\0')
       
    94 			(void) strlcat(apath, "/", PATH_MAX);
       
    95 		(void) strlcat(apath, path, PATH_MAX);
       
    96 	} else {
       
    97 		(void) strlcpy(apath, path, PATH_MAX);
       
    98 	}
       
    99 
       
   100 	if (resolvepath(apath, cpath, PATH_MAX) == -1 ||
       
   101 	    stat64(path, &st) == -1)
       
   102 		return (empty_file(data, apath, apath));
       
   103 
       
   104 	adr_struct_set(data, "absolutePath",
       
   105 	    adr_data_new_string(apath, LT_COPY));
       
   106 	adr_struct_set(data, "canonicalPath",
       
   107 	    adr_data_new_string(cpath, LT_COPY));
       
   108 	adr_struct_set(data, "canonical",
       
   109 	    adr_data_new_boolean(strcmp(apath, cpath) == 0));
       
   110 	adr_struct_set(data, "baseName",
       
   111 	    adr_data_new_string(basename(apath), LT_COPY));
       
   112 	adr_struct_set(data, "exists", adr_data_new_boolean(B_TRUE));
       
   113 	adr_struct_set(data, "readable",
       
   114 	    adr_data_new_boolean(access(path, R_OK) == 0));
       
   115 	adr_struct_set(data, "writable",
       
   116 	    adr_data_new_boolean(access(path, W_OK) == 0));
       
   117 	adr_struct_set(data, "hidden", adr_data_new_boolean(B_FALSE));
       
   118 	adr_struct_set(data, "directory",
       
   119 	    adr_data_new_boolean(S_ISDIR(st.st_mode)));
       
   120 	adr_struct_set(data, "file", adr_data_new_boolean(S_ISREG(st.st_mode)));
       
   121 	adr_struct_set(data, "lastModified", adr_data_new_time_ts(&st.st_mtim));
       
   122 	/* XXX: 64-bitify */
       
   123 	adr_struct_set(data, "length", adr_data_new_long(st.st_size));
       
   124 	adr_struct_set(data, "freeSpace", adr_data_new_long(0));
       
   125 	adr_struct_set(data, "totalSpace", adr_data_new_long(0));
       
   126 	adr_struct_set(data, "usableSpace", adr_data_new_long(0));
       
   127 	return (adr_data_purify(data));
       
   128 }
       
   129 
       
   130 /* ARGSUSED */
       
   131 conerr_t
       
   132 interface_FileBrowser_read_roots(rad_instance_t *inst, adr_attribute_t *attr,
       
   133     adr_data_t **data, adr_data_t **error)
       
   134 {
       
   135 	adr_data_t *result = adr_data_new_array(&t_array__FileSnapshot, 1);
       
   136 	(void) adr_array_add(result, read_file("/", NULL));
       
   137 	*data = adr_data_purify(result);
       
   138 	return (CE_OK);
       
   139 }
       
   140 
       
   141 /* ARGSUSED */
       
   142 conerr_t
       
   143 interface_FileBrowser_invoke_getFile(rad_instance_t *inst, adr_method_t *meth,
       
   144     adr_data_t **ret, adr_data_t **args, int count, adr_data_t **error)
       
   145 {
       
   146 	*ret = read_file(adr_data_to_string(args[0]), NULL);
       
   147 	return (CE_OK);
       
   148 }
       
   149 
       
   150 /* ARGSUSED */
       
   151 conerr_t
       
   152 interface_FileBrowser_invoke_getFiles(rad_instance_t *inst, adr_method_t *meth,
       
   153     adr_data_t **ret, adr_data_t **args, int count, adr_data_t **error)
       
   154 {
       
   155 	const char *path = adr_data_to_string(args[0]);
       
   156 	DIR *d = opendir(path);
       
   157 	struct dirent *ent;
       
   158 	adr_data_t *result;
       
   159 
       
   160 	if (d == NULL)
       
   161 		return (CE_OBJECT);
       
   162 
       
   163 	result = adr_data_new_array(&t_array__FileSnapshot, 1);
       
   164 	while ((ent = readdir(d)) != NULL) {
       
   165 		char buf[PATH_MAX];
       
   166 		if (strcmp(ent->d_name, ".") == 0 ||
       
   167 		    strcmp(ent->d_name, "..") == 0)
       
   168 			continue;
       
   169 		int len = strlen(path);
       
   170 		while (len > 0 && path[len - 1] == '/')
       
   171 			len--;
       
   172 		(void) snprintf(buf, PATH_MAX, "%.*s/%s", len, path,
       
   173 		    ent->d_name);
       
   174 		adr_data_t *file = read_file(buf, NULL);
       
   175 		if (file != NULL)
       
   176 			(void) adr_array_add(result, file);
       
   177 	}
       
   178 	(void) closedir(d);
       
   179 	*ret = adr_data_purify(result);
       
   180 
       
   181 	return (CE_OK);
       
   182 }
       
   183 
       
   184 int
       
   185 _rad_init(void)
       
   186 {
       
   187 	adr_name_t *aname = adr_name_vcreate(
       
   188 	    MOD_DOMAIN, 1, "type", "FileBrowser");
       
   189 	conerr_t cerr =  rad_cont_insert_singleton(rad_container, aname,
       
   190 	    &modinfo, &interface_FileBrowser_svr);
       
   191 	adr_name_rele(aname);
       
   192 	if (cerr != CE_OK) {
       
   193 		rad_log(RL_ERROR, "(mod_files) failed to insert FileBrowser");
       
   194 		return (-1);
       
   195 	}
       
   196 
       
   197 	return (0);
       
   198 }
       
   199 
       
   200 /*
       
   201  * _rad_fini is called by the RAD daemon when the module is unloaded. Any
       
   202  * module finalisation is completed here.
       
   203  */
       
   204 /*ARGSUSED*/
       
   205 void
       
   206 _rad_fini(void *unused)
       
   207 {
       
   208 }