2 * Copyright (c) 2001-2002 International Business Machines Corp.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
9 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
12 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
13 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
14 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
15 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
16 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
17 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
18 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 #include <afs/param.h>
28 #include "org_openafs_jafs_File.h"
34 #include <afs/afs_usrops.h>
35 #include <afs/prs_fs.h>
44 #define UAFS_DELETE 16
52 void setFileNotExistsAttributes(JNIEnv *env, jobject *obj);
59 /*static char compile_date[] = COMPILE_DATE;*/
61 int sub_time(struct timeval *tv1, struct timeval *tv2)
63 if (tv2->tv_usec > tv1->tv_usec) {
64 tv1->tv_usec += 1000000;
68 tv1->tv_usec -= tv2->tv_usec;
69 tv1->tv_sec -= tv2->tv_sec;
73 * Sets dirName to the absolute path according to the path field
74 * within the Java File object (obj).
76 * env the Java environment
77 * obj the current Java object
79 char* getAbsolutePath(JNIEnv *env, jobject *obj, char *dirName)
83 jmethodID getAbsolutePathID;
87 thisClass = (*env)->GetObjectClass(env, *obj);
88 if( thisClass == NULL ) {
89 fprintf(stderr, "File::getAbsolutePath(): GetObjectClass failed\n");
93 fid = (*env)->GetFieldID(env, thisClass, "path", "Ljava/lang/String;");
95 fprintf(stderr, "File::getAbsolutePath(): GetFieldID (path) failed\n");
99 jDirName = (*env)->GetObjectField(env, *obj, fid);
100 if( jDirName == NULL ) {
101 fprintf(stderr, "File::getAbsolutePath(): failed to get file name\n");
105 auxDirName = getNativeString(env, jDirName);
106 if ( auxDirName == NULL ) {
107 fprintf(stderr, "File::getAbsolutePath(): failed to get translated file name\n");
110 strcpy(dirName, auxDirName);
115 * Performs a file stat on the actual AFS file and populates
116 * the Java object's respective field members with the appropriate values.
117 * method will, if authorized, perform a stat on the
118 * actual AFS file and update its respective field members; defining
119 * this file object's attributes.
121 * env the Java environment
122 * obj the current Java object
124 * return true if and only if the current user is allowed to stat the file;
127 * throws AFSException
129 JNIEXPORT jboolean JNICALL Java_org_openafs_jafs_File_setAttributes
130 (JNIEnv *env, jobject obj)
132 char target[FILENAME_MAX+1];
133 char dirName[FILENAME_MAX];
139 jboolean islink = JNI_FALSE;
141 struct timeval tv0, tv1;
144 /*memset(target, 0, FILENAME_MAX);*/
147 getAbsolutePath(env, &obj, dirName);
149 /*fprintf(stderr, "dirName=%s\n", dirName);*/
151 if(*dirName == '\0') {
152 fprintf(stderr, "File::setAttributes(): failed to get dirName\n");
156 thisClass = (*env) -> GetObjectClass(env, obj);
157 if(thisClass == NULL) {
158 fprintf(stderr, "File::setAttributes(): GetObjectClass failed\n");
162 gettimeofday(&tv0, &tz);
163 if ((strcmp(dirName, "/afs") == 0) || (strcmp(dirName, "/afs/") == 0)) {
164 rc = 1; /* special case for /afs since statmountpoint fails on it */
166 rc = uafs_statmountpoint(dirName);
167 gettimeofday(&tv1, &tz);
168 sub_time(&tv1, &tv0);
169 /*printf("%s: statmountpoint %d.%06d\n", dirName, tv1.tv_sec, tv1.tv_usec);*/
173 setError(env, &obj, errno);
174 if(errno == ENOENT) {
175 setFileNotExistsAttributes(env, &obj);
176 return JNI_TRUE; /* not really an error */
178 fprintf(stderr, "File::setAttributes(): uafs_statmountpoint failed "
179 "for %s (%s)\n", dirName, error_message(errno));
185 /* this is an AFS mount point; we don't want to stat it */
186 /* fake up a stat entry instead */
190 st.st_mode = 0; /* don't match anything */
193 fid = (*env)->GetFieldID(env, thisClass, "isLink", "Z");
195 fprintf(stderr, "File::setAttributes(): GetFieldID (isLink) failed\n");
196 setError(env, &obj, -1);
199 islink = (*env)->GetBooleanField(env, obj, fid);
200 if (islink != JNI_TRUE) {
201 rc = uafs_lstat(dirName, &st);
203 /* Here we are being called on a link object for the second time,
204 so we want info on the object pointed to by the link. */
205 fprintf(stderr, "islink = TRUE on file %s\n", dirName);
206 rc = uafs_stat(dirName, &st);
210 setError(env, &obj, errno);
211 fprintf(stderr, "uafs_lstat failed for dir %s: error %d\n",
213 if(errno == ENOENT) {
214 setFileNotExistsAttributes(env, &obj);
218 "File::setAttributes(): uafs_stat failed for %s (%s)\n",
219 dirName, error_message(errno));
224 fid = (*env)->GetFieldID(env, thisClass, "exists", "Z");
227 "File::setAttributes(): GetFieldID (exists) failed\n");
228 setError(env, &obj, -1);
231 (*env)->SetBooleanField(env, obj, fid, JNI_TRUE);
233 fid = (*env)->GetFieldID(env, thisClass, "isDirectory", "Z");
236 "File::setAttributes(): GetFieldID (isDirectory) failed\n");
237 setError(env, &obj, -1);
240 if ((st.st_mode & S_IFMT) == S_IFDIR && !mtpoint) {
241 (*env)->SetBooleanField(env, obj, fid, JNI_TRUE);
243 (*env)->SetBooleanField(env, obj, fid, JNI_FALSE);
246 fid = (*env)->GetFieldID(env, thisClass, "isFile", "Z");
249 "File::setAttributes(): GetFieldID (isFile) failed\n");
250 setError(env, &obj, -1);
253 if ((st.st_mode & S_IFMT) == S_IFREG) {
254 (*env)->SetBooleanField(env, obj, fid, JNI_TRUE);
256 (*env)->SetBooleanField(env, obj, fid, JNI_FALSE);
259 fid = (*env)->GetFieldID(env, thisClass, "isLink", "Z");
262 "File::setAttributes(): GetFieldID (isLink) failed\n");
263 setError(env, &obj, -1);
267 if (islink != JNI_TRUE) { /* don't re-process link */
268 if ((st.st_mode & S_IFMT) == S_IFLNK) {
269 (*env)->SetBooleanField(env, obj, fid, JNI_TRUE);
271 /* Find the target of the link */
272 rc = uafs_readlink(dirName, target, FILENAME_MAX);
274 fprintf(stderr, "File::setAttributes(): uafs_readlink failed\n");
275 setError(env, &obj, errno);
278 target[rc] = 0; /* weird that we have to do this */
279 /*fprintf(stderr, "readlink %s succeeded, target=%s, rc=%d\n", dirName,
283 rc = setString(env, &obj, "target", target);
285 fprintf(stderr, "setString dirName=%s target=%s failed\n",
289 (*env)->SetBooleanField(env, obj, fid, JNI_FALSE);
293 fid = (*env)->GetFieldID(env, thisClass, "isMountPoint", "Z");
296 "File::setAttributes(): GetFieldID (isMountPoint) failed\n");
297 setError(env, &obj, -1);
302 (*env)->SetBooleanField(env, obj, fid, JNI_TRUE);
304 (*env)->SetBooleanField(env, obj, fid, JNI_FALSE);
307 fid = (*env)->GetFieldID(env, thisClass, "lastModified", "J");
310 "File::setAttributes(): GetFieldID (lastModified) failed\n");
311 setError(env, &obj, -1);
314 (*env)->SetLongField(env, obj, fid, ((jlong) st.st_mtime)*1000);
316 fid = (*env)->GetFieldID(env, thisClass, "length", "J");
319 "File::setAttributes(): GetFieldID (length) failed\n");
320 setError(env, &obj, -1);
323 (*env)->SetLongField(env, obj, fid, st.st_size);
325 setError(env, &obj, 0);
331 * Returns the permission/ACL mask for the represented directory
333 * env the Java environment
334 * obj the current Java object
336 * return permission/ACL mask
338 JNIEXPORT jint JNICALL Java_org_openafs_jafs_File_getRights
339 (JNIEnv *env, jobject obj)
341 char dirName[FILENAME_MAX];
349 getAbsolutePath(env, &obj, dirName);
351 if(*dirName == '\0') {
352 fprintf(stderr, "File::getRights(): failed to get dirName\n");
353 setError(env, &obj, -1);
368 afs_rights = uafs_getRights(dirName);
369 if (afs_rights < 0) {
370 setError(env, &obj, errno);
374 if (afs_rights & PRSFS_READ)
376 if (afs_rights & PRSFS_WRITE)
377 rights |= UAFS_WRITE;
378 if (afs_rights & PRSFS_INSERT)
379 rights |= UAFS_INSERT;
380 if (afs_rights & PRSFS_LOOKUP)
381 rights |= UAFS_LOOKUP;
382 if (afs_rights & PRSFS_DELETE)
383 rights |= UAFS_DELETE;
384 if (afs_rights & PRSFS_LOCK)
386 if (afs_rights & PRSFS_ADMINISTER)
387 rights |= UAFS_ADMIN;
394 * List the contents of the represented directory.
396 * env the Java environment
397 * obj the current Java object
399 * return the directory handle
401 JNIEXPORT jlong JNICALL Java_org_openafs_jafs_File_listNative
402 (JNIEnv *env, jobject obj, jobject buffer)
404 char dirName[FILENAME_MAX];
405 jclass arrayListClass;
407 jstring entryJString;
409 struct usr_dirent *enp;
413 getAbsolutePath(env, &obj, dirName);
414 if(*dirName == '\0') {
415 fprintf(stderr, "File::listNative(): failed to get dirName\n");
416 setError(env, &obj, -1);
419 arrayListClass = (*env)->GetObjectClass(env, buffer);
420 if(arrayListClass == NULL) {
421 fprintf(stderr, "File::listNative(): GetObjectClass failed\n");
422 setError(env, &obj, -1);
425 addID = (*env) -> GetMethodID(env, arrayListClass, "add",
426 "(Ljava/lang/Object;)Z");
429 "File::listNative(): failed to get addID\n");
430 setError(env, &obj, -1);
433 dirp = uafs_opendir(dirName);
435 fprintf(stderr, "File::listNative(): uafs_opendir(%s) failed(%s)\n",
436 dirName, error_message(errno));
437 setError(env, &obj, errno);
438 //throwAFSSecurityException( env, errno );
441 while((enp = uafs_readdir(dirp)) != NULL) {
442 if(strcmp(enp->d_name, ".") == 0 || strcmp(enp->d_name, "..") == 0) {
445 entryJString = (*env) -> NewStringUTF(env, enp->d_name);
446 if(entryJString == NULL) {
447 fprintf(stderr, "File::listNative(): NewStringUTF failed\n");
448 setError(env, &obj, -1);
451 (*env) -> CallBooleanMethod(env, buffer, addID, entryJString);
453 /*uafs_closedir(dirp);*/
455 setError(env, &obj, 0);
461 * Close the currently open directory using a provided directory handle.
463 * env the Java environment
464 * obj the current Java object
466 * return true if the directory closes without error
468 JNIEXPORT jboolean JNICALL Java_org_openafs_jafs_File_closeDir
469 (JNIEnv *env, jobject obj, jlong dp)
471 usr_DIR *dirp = (usr_DIR *) dp;
474 rc = uafs_closedir(dirp);
476 setError(env, &obj, errno);
485 * Removes/deletes the represented file.
487 * env the Java environment
488 * obj the current Java object
490 * return true if the file is removed without error
492 JNIEXPORT jboolean JNICALL Java_org_openafs_jafs_File_rmfile
493 (JNIEnv *env, jobject obj)
495 char dirName[FILENAME_MAX];
499 getAbsolutePath(env, &obj, dirName);
500 if(*dirName == '\0') {
501 setError(env, &obj, EINVAL);
502 fprintf(stderr, "File::rmfile(): failed to get dirName\n");
505 rc = uafs_unlink(dirName);
507 setError(env, &obj, errno);
508 fprintf(stderr, "File::rmfile(): uafs_unlink failed\n");
511 setError(env, &obj, 0);
516 * Removes/deletes the represented directory.
518 * env the Java environment
519 * obj the current Java object
521 * return true if the directory is removed without error
523 JNIEXPORT jboolean JNICALL Java_org_openafs_jafs_File_rmdir
524 (JNIEnv *env, jobject obj)
526 char dirName[FILENAME_MAX];
530 getAbsolutePath(env, &obj, dirName);
531 if(*dirName == '\0') {
532 setError(env, &obj, -1);
533 fprintf(stderr, "File::rmdir(): failed to get dirName\n");
536 rc = uafs_rmdir(dirName);
538 setError(env, &obj, errno);
539 fprintf(stderr, "File::rmdir(): uafs_unlink failed\n");
542 setError(env, &obj, 0);
547 * Creates the directory named by this abstract pathname.
549 * env the Java environment
550 * obj the current Java object
552 * return true if and only if the directory was
553 * created; false otherwise
555 JNIEXPORT jboolean JNICALL Java_org_openafs_jafs_File_mkdir
556 (JNIEnv *env, jobject obj)
558 char dirName[FILENAME_MAX];
562 getAbsolutePath(env, &obj, dirName);
563 if(*dirName == '\0') {
564 setError(env, &obj, EINVAL);
565 fprintf(stderr, "File::mkdir(): failed to get dirName\n");
568 rc = uafs_mkdir(dirName, 0755);
570 setError(env, &obj, errno);
571 fprintf(stderr, "File::mkdir(): uafs_mkdir failed\n");
574 setError(env, &obj, 0);
579 * Renames the file denoted by this abstract pathname.
581 * env the Java environment
582 * obj the current Java object
583 * dest the new abstract pathname for the named file
585 * return true if and only if the renaming succeeded;
588 * throws NullPointerException
589 * If parameter dest is null
591 JNIEXPORT jboolean JNICALL Java_org_openafs_jafs_File_renameTo
592 (JNIEnv *env, jobject obj, jobject newFile)
594 char thisDirName[FILENAME_MAX], newDirName[FILENAME_MAX];
598 getAbsolutePath(env, &obj, thisDirName);
599 if(*thisDirName == '\0') {
600 setError(env, &obj, -1);
601 fprintf(stderr, "File::renameTo(): failed to get dirName for this \n");
605 getAbsolutePath(env, &newFile, newDirName);
606 if(*newDirName == '\0') {
607 setError(env, &obj, -1);
608 fprintf(stderr, "File::renameTo(): failed to get dirName for new \n");
611 rc = uafs_rename(thisDirName, newDirName);
613 setError(env, &obj, errno);
614 fprintf(stderr, "File::renameTo(): uafs_rename failed\n");
621 * Set all the necessary fields within the Java File class to indicate the
624 * env the Java environment
625 * obj the current Java object
627 void setFileNotExistsAttributes
628 (JNIEnv *env, jobject *obj)
633 thisClass = (*env) -> GetObjectClass(env, *obj);
634 if(thisClass == NULL) {
636 "File::setFileNotExistsAttributes(): GetObjectClass failed\n");
640 fid = (*env)->GetFieldID(env, thisClass, "exists", "Z");
643 "File::setFileNotExistsAttributes(): GetFieldID (exists) failed\n");
646 (*env)->SetBooleanField(env, *obj, fid, JNI_FALSE);
648 fid = (*env)->GetFieldID(env, thisClass, "isDirectory", "Z");
651 "File::setFileNotExistsAttributes(): GetFieldID (isDirectory) failed\n");
654 (*env)->SetBooleanField(env, *obj, fid, JNI_FALSE);
656 fid = (*env)->GetFieldID(env, thisClass, "isFile", "Z");
659 "File::setFileNotExistsAttributes(): GetFieldID (isDirectory) failed\n");
662 (*env)->SetBooleanField(env, *obj, fid, JNI_FALSE);
664 fid = (*env)->GetFieldID(env, thisClass, "lastModified", "J");
667 "File::setFileNotExistsAttributes(): GetFieldID (lastModified) failed\n");
670 (*env)->SetLongField(env, *obj, fid, 0);
673 fid = (*env)->GetFieldID(env, thisClass, "length", "J");
676 "File::setFileNotExistsAttributes(): GetFieldID (length) failed\n");
679 (*env)->SetLongField(env, *obj, fid, 0);