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.
22 #include <afs/param.h>
23 #include <afs/com_err.h>
27 #include "org_openafs_jafs_File.h"
33 /*#include <afs/afs_usrops.h>*/
34 #include <afs/prs_fs.h>
43 #define UAFS_DELETE 16
51 void setFileNotExistsAttributes(JNIEnv
*env
, jobject
*obj
);
58 /*static char compile_date[] = COMPILE_DATE;*/
60 int sub_time(struct timeval
*tv1
, struct timeval
*tv2
)
62 if (tv2
->tv_usec
> tv1
->tv_usec
) {
63 tv1
->tv_usec
+= 1000000;
67 tv1
->tv_usec
-= tv2
->tv_usec
;
68 tv1
->tv_sec
-= tv2
->tv_sec
;
72 * Sets dirName to the absolute path according to the path field
73 * within the Java File object (obj).
75 * env the Java environment
76 * obj the current Java object
78 char* getAbsolutePath(JNIEnv
*env
, jobject
*obj
, char *dirName
)
82 jmethodID getAbsolutePathID
;
83 const char *auxDirName
;
86 thisClass
= (*env
)->GetObjectClass(env
, *obj
);
87 if(thisClass
== NULL
) {
88 fprintf(stderr
, "File::getAbsolutePath(): GetObjectClass failed\n");
91 fid
= (*env
)->GetFieldID(env
, thisClass
, "path", "Ljava/lang/String;");
93 fprintf(stderr
, "File::getAbsolutePath(): GetFieldID (path) failed\n");
96 jDirName
= (*env
)->GetObjectField(env
, *obj
, fid
);
98 if(jDirName
== NULL
) {
99 fprintf(stderr
, "File::getAbsolutePath(): failed to get file name\n");
102 auxDirName
= (*env
) -> GetStringUTFChars(env
, jDirName
, 0);
103 strcpy(dirName
, auxDirName
);
104 (*env
) -> ReleaseStringUTFChars(env
, jDirName
, auxDirName
);
108 * Performs a file stat on the actual AFS file and populates
109 * the Java object's respective field members with the appropriate values.
110 * method will, if authorized, perform a stat on the
111 * actual AFS file and update its respective field members; defining
112 * this file object's attributes.
114 * env the Java environment
115 * obj the current Java object
117 * return true if and only if the current user is allowed to stat the file;
120 * throws AFSException
122 JNIEXPORT jboolean JNICALL Java_org_openafs_jafs_File_setAttributes
123 (JNIEnv
*env
, jobject obj
)
125 char target
[FILENAME_MAX
+1];
126 char dirName
[FILENAME_MAX
];
132 jboolean islink
= JNI_FALSE
;
134 struct timeval tv0
, tv1
;
136 /*memset(target, 0, FILENAME_MAX);*/
139 getAbsolutePath(env
, &obj
, dirName
);
141 /*fprintf(stderr, "dirName=%s\n", dirName);*/
143 if(*dirName
== '\0') {
144 fprintf(stderr
, "File::setAttributes(): failed to get dirName\n");
148 thisClass
= (*env
) -> GetObjectClass(env
, obj
);
149 if(thisClass
== NULL
) {
150 fprintf(stderr
, "File::setAttributes(): GetObjectClass failed\n");
154 gettimeofday(&tv0
, NULL
);
155 if ((strcmp(dirName
, "/afs") == 0) || (strcmp(dirName
, "/afs/") == 0)) {
156 rc
= 1; /* special case for /afs since statmountpoint fails on it */
158 rc
= uafs_statmountpoint(dirName
);
159 gettimeofday(&tv1
, NULL
);
160 sub_time(&tv1
, &tv0
);
161 /*printf("%s: statmountpoint %d.%06d\n", dirName, tv1.tv_sec, tv1.tv_usec);*/
165 setError(env
, &obj
, errno
);
166 if(errno
== ENOENT
) {
167 setFileNotExistsAttributes(env
, &obj
);
168 return JNI_TRUE
; /* not really an error */
170 fprintf(stderr
, "File::setAttributes(): uafs_statmountpoint failed "
171 "for %s (%s)\n", dirName
, afs_error_message(errno
));
177 /* this is an AFS mount point; we don't want to stat it */
178 /* fake up a stat entry instead */
182 st
.st_mode
= 0; /* don't match anything */
185 fid
= (*env
)->GetFieldID(env
, thisClass
, "isLink", "Z");
187 fprintf(stderr
, "File::setAttributes(): GetFieldID (isLink) failed\n");
188 setError(env
, &obj
, -1);
191 islink
= (*env
)->GetBooleanField(env
, obj
, fid
);
192 if (islink
!= JNI_TRUE
) {
193 rc
= uafs_lstat(dirName
, &st
);
195 /* Here we are being called on a link object for the second time,
196 so we want info on the object pointed to by the link. */
197 fprintf(stderr
, "islink = TRUE on file %s\n", dirName
);
198 rc
= uafs_stat(dirName
, &st
);
202 setError(env
, &obj
, errno
);
203 fprintf(stderr
, "uafs_lstat failed for dir %s: error %d\n",
205 if(errno
== ENOENT
) {
206 setFileNotExistsAttributes(env
, &obj
);
210 "File::setAttributes(): uafs_stat failed for %s (%s)\n",
211 dirName
, afs_error_message(errno
));
216 fid
= (*env
)->GetFieldID(env
, thisClass
, "exists", "Z");
219 "File::setAttributes(): GetFieldID (exists) failed\n");
220 setError(env
, &obj
, -1);
223 (*env
)->SetBooleanField(env
, obj
, fid
, JNI_TRUE
);
225 fid
= (*env
)->GetFieldID(env
, thisClass
, "isDirectory", "Z");
228 "File::setAttributes(): GetFieldID (isDirectory) failed\n");
229 setError(env
, &obj
, -1);
232 if ((st
.st_mode
& S_IFMT
) == S_IFDIR
&& !mtpoint
) {
233 (*env
)->SetBooleanField(env
, obj
, fid
, JNI_TRUE
);
235 (*env
)->SetBooleanField(env
, obj
, fid
, JNI_FALSE
);
238 fid
= (*env
)->GetFieldID(env
, thisClass
, "isFile", "Z");
241 "File::setAttributes(): GetFieldID (isFile) failed\n");
242 setError(env
, &obj
, -1);
245 if ((st
.st_mode
& S_IFMT
) == S_IFREG
) {
246 (*env
)->SetBooleanField(env
, obj
, fid
, JNI_TRUE
);
248 (*env
)->SetBooleanField(env
, obj
, fid
, JNI_FALSE
);
251 fid
= (*env
)->GetFieldID(env
, thisClass
, "isLink", "Z");
254 "File::setAttributes(): GetFieldID (isLink) failed\n");
255 setError(env
, &obj
, -1);
259 if (islink
!= JNI_TRUE
) { /* don't re-process link */
260 if ((st
.st_mode
& S_IFMT
) == S_IFLNK
) {
261 (*env
)->SetBooleanField(env
, obj
, fid
, JNI_TRUE
);
263 /* Find the target of the link */
264 rc
= uafs_readlink(dirName
, target
, FILENAME_MAX
);
266 fprintf(stderr
, "File::setAttributes(): uafs_readlink failed\n");
267 setError(env
, &obj
, errno
);
270 target
[rc
] = 0; /* weird that we have to do this */
271 /*fprintf(stderr, "readlink %s succeeded, target=%s, rc=%d\n", dirName,
275 rc
= setString(env
, &obj
, "target", target
);
277 fprintf(stderr
, "setString dirName=%s target=%s failed\n",
281 (*env
)->SetBooleanField(env
, obj
, fid
, JNI_FALSE
);
285 fid
= (*env
)->GetFieldID(env
, thisClass
, "isMountPoint", "Z");
288 "File::setAttributes(): GetFieldID (isMountPoint) failed\n");
289 setError(env
, &obj
, -1);
294 (*env
)->SetBooleanField(env
, obj
, fid
, JNI_TRUE
);
296 (*env
)->SetBooleanField(env
, obj
, fid
, JNI_FALSE
);
299 fid
= (*env
)->GetFieldID(env
, thisClass
, "lastModified", "J");
302 "File::setAttributes(): GetFieldID (lastModified) failed\n");
303 setError(env
, &obj
, -1);
306 (*env
)->SetLongField(env
, obj
, fid
, ((jlong
) st
.st_mtime
)*1000);
308 fid
= (*env
)->GetFieldID(env
, thisClass
, "length", "J");
311 "File::setAttributes(): GetFieldID (length) failed\n");
312 setError(env
, &obj
, -1);
315 (*env
)->SetLongField(env
, obj
, fid
, st
.st_size
);
317 setError(env
, &obj
, 0);
323 * Returns the permission/ACL mask for the represented directory
325 * env the Java environment
326 * obj the current Java object
328 * return permission/ACL mask
330 JNIEXPORT jint JNICALL Java_org_openafs_jafs_File_getRights
331 (JNIEnv
*env
, jobject obj
)
333 char dirName
[FILENAME_MAX
];
341 getAbsolutePath(env
, &obj
, dirName
);
343 if(*dirName
== '\0') {
344 fprintf(stderr
, "File::getRights(): failed to get dirName\n");
345 setError(env
, &obj
, -1);
360 afs_rights
= uafs_getRights(dirName
);
361 if (afs_rights
< 0) {
362 setError(env
, &obj
, errno
);
366 if (afs_rights
& PRSFS_READ
)
368 if (afs_rights
& PRSFS_WRITE
)
369 rights
|= UAFS_WRITE
;
370 if (afs_rights
& PRSFS_INSERT
)
371 rights
|= UAFS_INSERT
;
372 if (afs_rights
& PRSFS_LOOKUP
)
373 rights
|= UAFS_LOOKUP
;
374 if (afs_rights
& PRSFS_DELETE
)
375 rights
|= UAFS_DELETE
;
376 if (afs_rights
& PRSFS_LOCK
)
378 if (afs_rights
& PRSFS_ADMINISTER
)
379 rights
|= UAFS_ADMIN
;
386 * List the contents of the represented directory.
388 * env the Java environment
389 * obj the current Java object
391 * return the directory handle
393 JNIEXPORT jlong JNICALL Java_org_openafs_jafs_File_listNative
394 (JNIEnv
*env
, jobject obj
, jobject buffer
)
398 char dirName
[FILENAME_MAX
];
399 jclass arrayListClass
;
401 jstring entryJString
;
403 struct usr_dirent
*enp
;
407 getAbsolutePath(env
, &obj
, dirName
);
408 if(*dirName
== '\0') {
409 fprintf(stderr
, "File::listNative(): failed to get dirName\n");
410 setError(env
, &obj
, -1);
413 arrayListClass
= (*env
)->GetObjectClass(env
, buffer
);
414 if(arrayListClass
== NULL
) {
415 fprintf(stderr
, "File::listNative(): GetObjectClass failed\n");
416 setError(env
, &obj
, -1);
419 addID
= (*env
) -> GetMethodID(env
, arrayListClass
, "add",
420 "(Ljava/lang/Object;)Z");
423 "File::listNative(): failed to get addID\n");
424 setError(env
, &obj
, -1);
427 dirp
= uafs_opendir(dirName
);
429 fprintf(stderr
, "File::listNative(): uafs_opendir(%s) failed(%s)\n",
430 dirName
, afs_error_message(errno
));
431 setError(env
, &obj
, errno
);
432 //throwAFSSecurityException( env, errno );
435 while((enp
= uafs_readdir(dirp
)) != NULL
) {
436 if(strcmp(enp
->d_name
, ".") == 0 || strcmp(enp
->d_name
, "..") == 0) {
439 entryJString
= (*env
) -> NewStringUTF(env
, enp
->d_name
);
440 if(entryJString
== NULL
) {
441 fprintf(stderr
, "File::listNative(): NewStringUTF failed\n");
442 setError(env
, &obj
, -1);
445 (*env
) -> CallBooleanMethod(env
, buffer
, addID
, entryJString
);
447 /*uafs_closedir(dirp);*/
449 setError(env
, &obj
, 0);
456 * Close the currently open directory using a provided directory handle.
458 * env the Java environment
459 * obj the current Java object
461 * return true if the directory closes without error
463 JNIEXPORT jboolean JNICALL Java_org_openafs_jafs_File_closeDir
464 (JNIEnv
*env
, jobject obj
, jlong dp
)
470 usr_DIR
*dirp
= (usr_DIR
*) dp
;
473 rc
= uafs_closedir(dirp
);
475 setError(env
, &obj
, errno
);
478 else return JNI_TRUE
;
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);