• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <grp.h>
18 #include <jni.h>
19 #include <pwd.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <sys/errno.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 
26 static jclass gFileStatusClass;
27 static jfieldID gFileStatusDevFieldID;
28 static jfieldID gFileStatusInoFieldID;
29 static jfieldID gFileStatusModeFieldID;
30 static jfieldID gFileStatusNlinkFieldID;
31 static jfieldID gFileStatusUidFieldID;
32 static jfieldID gFileStatusGidFieldID;
33 static jfieldID gFileStatusSizeFieldID;
34 static jfieldID gFileStatusBlksizeFieldID;
35 static jfieldID gFileStatusBlocksFieldID;
36 static jfieldID gFileStatusAtimeFieldID;
37 static jfieldID gFileStatusMtimeFieldID;
38 static jfieldID gFileStatusCtimeFieldID;
39 
40 /*
41  * Native methods used by
42  * cts/tests/src/android/os/cts/FileUtils.java
43  *
44  * Copied from hidden API: frameworks/base/core/jni/android_os_FileUtils.cpp
45  */
46 
android_os_cts_FileUtils_getFileStatus(JNIEnv * env,jobject thiz,jstring path,jobject fileStatus,jboolean statLinks)47 jboolean android_os_cts_FileUtils_getFileStatus(JNIEnv* env, jobject thiz,
48         jstring path, jobject fileStatus, jboolean statLinks)
49 {
50     const char* pathStr = env->GetStringUTFChars(path, NULL);
51     jboolean ret = false;
52     struct stat s;
53 
54     int res = statLinks == true ? lstat(pathStr, &s) : stat(pathStr, &s);
55 
56     if (res == 0) {
57         ret = true;
58         if (fileStatus != NULL) {
59             env->SetIntField(fileStatus, gFileStatusDevFieldID, s.st_dev);
60             env->SetIntField(fileStatus, gFileStatusInoFieldID, s.st_ino);
61             env->SetIntField(fileStatus, gFileStatusModeFieldID, s.st_mode);
62             env->SetIntField(fileStatus, gFileStatusNlinkFieldID, s.st_nlink);
63             env->SetIntField(fileStatus, gFileStatusUidFieldID, s.st_uid);
64             env->SetIntField(fileStatus, gFileStatusGidFieldID, s.st_gid);
65             env->SetLongField(fileStatus, gFileStatusSizeFieldID, s.st_size);
66             env->SetIntField(fileStatus, gFileStatusBlksizeFieldID, s.st_blksize);
67             env->SetLongField(fileStatus, gFileStatusBlocksFieldID, s.st_blocks);
68             env->SetLongField(fileStatus, gFileStatusAtimeFieldID, s.st_atime);
69             env->SetLongField(fileStatus, gFileStatusMtimeFieldID, s.st_mtime);
70             env->SetLongField(fileStatus, gFileStatusCtimeFieldID, s.st_ctime);
71         }
72     }
73 
74     env->ReleaseStringUTFChars(path, pathStr);
75 
76     return ret;
77 }
78 
android_os_cts_FileUtils_getUserName(JNIEnv * env,jobject thiz,jint uid)79 jstring android_os_cts_FileUtils_getUserName(JNIEnv* env, jobject thiz,
80         jint uid)
81 {
82     struct passwd *pwd = getpwuid(uid);
83     return env->NewStringUTF(pwd->pw_name);
84 }
85 
android_os_cts_FileUtils_getGroupName(JNIEnv * env,jobject thiz,jint gid)86 jstring android_os_cts_FileUtils_getGroupName(JNIEnv* env, jobject thiz,
87         jint gid)
88 {
89     struct group *grp = getgrgid(gid);
90     return env->NewStringUTF(grp->gr_name);
91 }
92 
android_os_cts_FileUtils_setPermissions(JNIEnv * env,jobject clazz,jstring file,jint mode)93 jint android_os_cts_FileUtils_setPermissions(JNIEnv* env, jobject clazz,
94         jstring file, jint mode)
95 {
96     const char *fileStr = env->GetStringUTFChars(file, NULL);
97     if (fileStr == NULL) {
98         return -1;
99     }
100 
101     if (strlen(fileStr) <= 0) {
102         env->ReleaseStringUTFChars(file, fileStr);
103         return ENOENT;
104     }
105 
106     jint returnValue = chmod(fileStr, mode) == 0 ? 0 : errno;
107     env->ReleaseStringUTFChars(file, fileStr);
108     return returnValue;
109 }
110 
111 static JNINativeMethod gMethods[] = {
112     {  "getFileStatus", "(Ljava/lang/String;Landroid/os/cts/FileUtils$FileStatus;Z)Z",
113             (void *) android_os_cts_FileUtils_getFileStatus  },
114     {  "getUserName", "(I)Ljava/lang/String;",
115             (void *) android_os_cts_FileUtils_getUserName  },
116     {  "getGroupName", "(I)Ljava/lang/String;",
117             (void *) android_os_cts_FileUtils_getGroupName  },
118     {  "setPermissions", "(Ljava/lang/String;I)I",
119             (void *) android_os_cts_FileUtils_setPermissions },
120 };
121 
register_android_os_cts_FileUtils(JNIEnv * env)122 int register_android_os_cts_FileUtils(JNIEnv* env)
123 {
124     jclass clazz = env->FindClass("android/os/cts/FileUtils");
125 
126     gFileStatusClass = env->FindClass("android/os/cts/FileUtils$FileStatus");
127     gFileStatusDevFieldID = env->GetFieldID(gFileStatusClass, "dev", "I");
128     gFileStatusInoFieldID = env->GetFieldID(gFileStatusClass, "ino", "I");
129     gFileStatusModeFieldID = env->GetFieldID(gFileStatusClass, "mode", "I");
130     gFileStatusNlinkFieldID = env->GetFieldID(gFileStatusClass, "nlink", "I");
131     gFileStatusUidFieldID = env->GetFieldID(gFileStatusClass, "uid", "I");
132     gFileStatusGidFieldID = env->GetFieldID(gFileStatusClass, "gid", "I");
133     gFileStatusSizeFieldID = env->GetFieldID(gFileStatusClass, "size", "J");
134     gFileStatusBlksizeFieldID = env->GetFieldID(gFileStatusClass, "blksize", "I");
135     gFileStatusBlocksFieldID = env->GetFieldID(gFileStatusClass, "blocks", "J");
136     gFileStatusAtimeFieldID = env->GetFieldID(gFileStatusClass, "atime", "J");
137     gFileStatusMtimeFieldID = env->GetFieldID(gFileStatusClass, "mtime", "J");
138     gFileStatusCtimeFieldID = env->GetFieldID(gFileStatusClass, "ctime", "J");
139 
140     return env->RegisterNatives(clazz, gMethods,
141             sizeof(gMethods) / sizeof(JNINativeMethod));
142 }
143