123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215 |
- /* java_io_VMFile.c - Native methods for java.io.File class
- Copyright (C) 1998, 2004, 2006 Free Software Foundation, Inc.
- This file is part of GNU Classpath.
- GNU Classpath is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- GNU Classpath is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNU Classpath; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
- Linking this library statically or dynamically with other modules is
- making a combined work based on this library. Thus, the terms and
- conditions of the GNU General Public License cover the whole
- combination.
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent
- modules, and to copy and distribute the resulting executable under
- terms of your choice, provided that you also meet, for each linked
- independent module, the terms and conditions of the license of that
- module. An independent module is a module which is not derived from
- or based on this library. If you modify this library, you may extend
- this exception to your version of the library, but you are not
- obligated to do so. If you do not wish to do so, delete this
- exception statement from your version. */
- /* do not move; needed here because of some macro definitions */
- #include <config.h>
- #include <assert.h>
- #include <stdio.h>
- #include <stdlib.h>
- #if defined (HAVE_LSTAT) && defined (HAVE_READLINK)
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #endif
- #include <jni.h>
- #include <jcl.h>
- #include "cpio.h"
- #include "cpnative.h"
- #include "java_io_VMFile.h"
- /* ***** PRIVATE FUNCTIONS DELCARATION ***** */
- /**
- * Enables of disables the passed permission bit of a file.
- */
- static jboolean set_file_permissions (JNIEnv *env, jstring name,
- jboolean enable,
- jboolean ownerOnly,
- int permissions);
- /* ***** END: PRIVATE FUNCTIONS DELCARATION ***** */
- /*************************************************************************/
- /*
- * Method to create an empty file.
- *
- * Class: java_io_VMFile
- * Method: create
- * Signature: (Ljava/lang/String;)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_create (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- int fd;
- int result;
- filename = JCL_jstring_to_cstring (env, name);
- if (filename == NULL)
- {
- return 0;
- }
- result = cpio_openFile (filename, &fd, CPFILE_FLAG_CREATE|CPFILE_FLAG_WRITE, CPFILE_PERMISSION_NORMAL);
- if (result != CPNATIVE_OK)
- {
- if (result != EEXIST)
- JCL_ThrowException (env,
- "java/io/IOException",
- cpnative_getErrorString (result));
- JCL_free_cstring (env, name, filename);
- return 0;
- }
- cpio_closeFile (fd);
- JCL_free_cstring (env, name, filename);
- return 1;
- #else /* not WITHOUT_FILESYSTEM */
- return 0;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method checks to see if we have read permission on a file.
- *
- * Class: java_io_VMFile
- * Method: canRead
- * Signature: (Ljava/lang/String;)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_canRead (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- int result;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- filename = (*env)->GetStringUTFChars (env, name, 0);
- if (filename == NULL)
- {
- return JNI_FALSE;
- }
- result = cpio_checkAccess (filename, CPFILE_FLAG_READ);
-
- (*env)->ReleaseStringUTFChars (env, name, filename);
- if (result != CPNATIVE_OK)
- return JNI_FALSE;
- return JNI_TRUE;
- #else /* not WITHOUT_FILESYSTEM */
- return JNI_FALSE;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method checks to see if we have write permission on a file.
- *
- * Class: java_io_VMFile
- * Method: canWrite
- * Signature: (Ljava/lang/String;)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_canWrite (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- int result;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- filename = (*env)->GetStringUTFChars (env, name, 0);
- if (filename == NULL)
- {
- return JNI_FALSE;
- }
- result = cpio_checkAccess (filename, CPFILE_FLAG_WRITE);
-
- (*env)->ReleaseStringUTFChars (env, name, filename);
- if (result != CPNATIVE_OK)
- {
- return JNI_FALSE;
- }
- return JNI_TRUE;
- #else /* not WITHOUT_FILESYSTEM */
- return JNI_FALSE;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_canWriteDirectory (JNIEnv *env, jclass clazz, jstring path)
- {
- /* this is only valid on *nix systems */
- return Java_java_io_VMFile_canWrite(env, clazz, path);
- }
- /*************************************************************************/
- /*
- * This method checks to see if we have execute permission on a file.
- *
- * Class: java_io_VMFile
- * Method: canExecute
- * Signature: (Ljava/lang/String;)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_canExecute (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- int result;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- filename = (*env)->GetStringUTFChars (env, name, 0);
- if (filename == NULL)
- {
- return JNI_FALSE;
- }
- result = cpio_checkAccess (filename, CPFILE_FLAG_EXEC);
-
- (*env)->ReleaseStringUTFChars (env, name, filename);
- if (result != CPNATIVE_OK)
- return JNI_FALSE;
-
- return JNI_TRUE;
- #else /* not WITHOUT_FILESYSTEM */
- return JNI_FALSE;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method makes a file read only.
- *
- * Class: java_io_VMFile
- * Method: setReadOnly
- * Signature: (Ljava/lang/String;)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_setReadOnly (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- int result;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- filename = (*env)->GetStringUTFChars (env, name, 0);
- if (filename == NULL)
- {
- return 0;
- }
- result = cpio_setFileReadonly (filename);
- (*env)->ReleaseStringUTFChars (env, name, filename);
- return result == CPNATIVE_OK ? 1 : 0;
- #else /* not WITHOUT_FILESYSTEM */
- return 0;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method changes the read permission bit of a file.
- *
- * Class: java_io_VMFile
- * Method: setReadable
- * Signature: (Ljava/lang/String;ZZ)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_setReadable (JNIEnv *env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name,
- jboolean readable,
- jboolean ownerOnly)
- {
- return set_file_permissions (env, name, readable, ownerOnly,
- CPFILE_FLAG_READ);
- }
- /*************************************************************************/
- /*
- * This method changes the write permission bit of a file.
- *
- * Class: java_io_VMFile
- * Method: setWritable
- * Signature: (Ljava/lang/String;ZZ)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_setWritable (JNIEnv *env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name,
- jboolean writable,
- jboolean ownerOnly)
- {
- return set_file_permissions (env, name, writable, ownerOnly,
- CPFILE_FLAG_WRITE);
- }
- /*************************************************************************/
- /*
- * This method changes the execute permission bit of a file.
- *
- * Class: java_io_VMFile
- * Method: setExecutable
- * Signature: (Ljava/lang/String;ZZ)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_setExecutable (JNIEnv *env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name,
- jboolean executable,
- jboolean ownerOnly)
- {
- return set_file_permissions (env, name, executable, ownerOnly,
- CPFILE_FLAG_EXEC);
- }
- /*************************************************************************/
- JNIEXPORT jlong JNICALL
- Java_java_io_VMFile_getTotalSpace (JNIEnv *env,
- jclass clazz __attribute__ ((__unused__)),
- jstring path)
- {
- #ifndef WITHOUT_FILESYSTEM
-
- jlong result;
- const char *_path = NULL;
-
- _path = (*env)->GetStringUTFChars (env, path, 0);
- if (_path == NULL)
- {
- return 0L;
- }
- result = cpio_df (_path, TOTAL);
- (*env)->ReleaseStringUTFChars (env, path, _path);
- return result;
- #else /* not WITHOUT_FILESYSTEM */
- return 0L;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- JNIEXPORT jlong JNICALL
- Java_java_io_VMFile_getFreeSpace (JNIEnv *env,
- jclass clazz __attribute__ ((__unused__)),
- jstring path)
- {
- #ifndef WITHOUT_FILESYSTEM
-
- jlong result;
- const char *_path = NULL;
-
- _path = (*env)->GetStringUTFChars (env, path, 0);
- if (_path == NULL)
- {
- return 0L;
- }
- result = cpio_df (_path, FREE);
- (*env)->ReleaseStringUTFChars (env, path, _path);
- return result;
- #else /* not WITHOUT_FILESYSTEM */
- return 0L;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- JNIEXPORT jlong JNICALL
- Java_java_io_VMFile_getUsableSpace (JNIEnv *env,
- jclass clazz __attribute__ ((__unused__)),
- jstring path)
- {
- #ifndef WITHOUT_FILESYSTEM
-
- jlong result;
- const char *_path = NULL;
-
- _path = (*env)->GetStringUTFChars (env, path, 0);
- if (_path == NULL)
- {
- return 0L;
- }
- result = cpio_df (_path, USABLE);
- (*env)->ReleaseStringUTFChars (env, path, _path);
- return result;
- #else /* not WITHOUT_FILESYSTEM */
- return 0L;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method checks to see if a file exists.
- *
- * Class: java_io_VMFile
- * Method: exists
- * Signature: (Ljava/lang/String;)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_exists (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- int result;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- filename = (*env)->GetStringUTFChars (env, name, 0);
- if (filename == NULL)
- {
- return 0;
- }
- result = cpio_isFileExists (filename);
- (*env)->ReleaseStringUTFChars (env, name, filename);
- return result == CPNATIVE_OK ? 1 : 0;
- #else /* not WITHOUT_FILESYSTEM */
- return 0;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method checks to see if a file is a "plain" file; that is, not
- * a directory, pipe, etc.
- *
- * Class: java_io_VMFile
- * Method: isFile
- * Signature: (Ljava/lang/String;)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_isFile (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- int result;
- jint entryType;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- filename = (*env)->GetStringUTFChars (env, name, 0);
- if (filename == NULL)
- {
- return 0;
- }
- result = cpio_checkType (filename, &entryType);
- (*env)->ReleaseStringUTFChars (env, name, filename);
- return result == CPNATIVE_OK && entryType == CPFILE_FILE ? 1 : 0;
- #else /* not WITHOUT_FILESYSTEM */
- return 0;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method checks to see if a file is a directory or not.
- *
- * Class: java_io_VMFile
- * Method: isDirectory
- * Signature: (Ljava/lang/String;)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_isDirectory (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- int result;
- jint entryType;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- filename = (*env)->GetStringUTFChars (env, name, 0);
- if (filename == NULL)
- {
- return 0;
- }
-
- result = cpio_checkType (filename, &entryType);
- (*env)->ReleaseStringUTFChars (env, name, filename);
- return result == CPNATIVE_OK && entryType == CPFILE_DIRECTORY ? 1 : 0;
- #else /* not WITHOUT_FILESYSTEM */
- return 0;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method returns the length of the file.
- *
- * Class: java_io_VMFile
- * Method: length
- * Signature: (Ljava/lang/String;)J
- */
- JNIEXPORT jlong JNICALL
- Java_java_io_VMFile_length (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- int tmpfd;
- jlong length;
- int result;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- filename = (*env)->GetStringUTFChars (env, name, 0);
- if (filename == NULL)
- return 0;
- /* open file for reading, get size and close file */
- result = cpio_openFile (filename, &tmpfd, CPFILE_FLAG_READ, 0);
- if (result != CPNATIVE_OK)
- return 0;
- result = cpio_getFileSize (tmpfd, &length);
- if (result != CPNATIVE_OK)
- {
- cpio_closeFile (tmpfd);
- return 0;
- }
- result = cpio_closeFile (tmpfd);
- (*env)->ReleaseStringUTFChars (env, name, filename);
- return result == CPNATIVE_OK ? length : 0;
- #else /* not WITHOUT_FILESYSTEM */
- return 0;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method returns the modification date of the file.
- *
- * Class: java_io_VMFile
- * Method: lastModified
- * Signature: (Ljava/lang/String;)J
- */
- JNIEXPORT jlong JNICALL
- Java_java_io_VMFile_lastModified (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- jlong mtime;
- int result;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- filename = (*env)->GetStringUTFChars (env, name, 0);
- if (filename == NULL)
- {
- return 0;
- }
- result = cpio_getModificationTime (filename, &mtime);
- (*env)->ReleaseStringUTFChars (env, name, filename);
- return result == CPNATIVE_OK ? mtime : 0;
- #else /* not WITHOUT_FILESYSTEM */
- return 0;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method sets the modification date of the file.
- *
- * Class: java_io_VMFile
- * Method: setLastModified
- * Signature: (Ljava/lang/String;J)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_setLastModified (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name, jlong newtime)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- int result;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- filename = (*env)->GetStringUTFChars (env, name, 0);
- if (filename == NULL)
- {
- return 0;
- }
- result = cpio_setModificationTime (filename, newtime);
- (*env)->ReleaseStringUTFChars (env, name, filename);
- return result == CPNATIVE_OK ? 1 : 0;
- #else /* not WITHOUT_FILESYSTEM */
- return 0;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method deletes a file (actually a name for a file - additional
- * links could exist).
- *
- * Class: java_io_VMFile
- * Method: delete
- * Signature: (Ljava/lang/String;)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_delete (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- int result;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- filename = (*env)->GetStringUTFChars (env, name, 0);
- if (filename == NULL)
- {
- return 0;
- }
- result = cpio_removeFile (filename);
- (*env)->ReleaseStringUTFChars (env, name, filename);
- return result == CPNATIVE_OK ? 1 : 0;
- #else /* not WITHOUT_FILESYSTEM */
- return 0;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method creates a directory.
- *
- * Class: java_io_VMFile
- * Method: mkdir
- * Signature: (Ljava/lang/String;)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_mkdir (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *pathname;
- int result;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- pathname = (*env)->GetStringUTFChars (env, name, 0);
- if (pathname == NULL)
- {
- return 0;
- }
- result = cpio_mkdir (pathname);
- (*env)->ReleaseStringUTFChars (env, name, pathname);
- return (result == CPNATIVE_OK) ? 1 : 0;
- #else /* not WITHOUT_FILESYSTEM */
- return 0;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method renames a (link to a) file.
- *
- * Class: java_io_VMFile
- * Method: renameTo
- * Signature: (Ljava/lang/String;Ljava/lang/String;)Z
- */
- JNIEXPORT jboolean JNICALL
- Java_java_io_VMFile_renameTo (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring t, jstring d)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *old_filename, *new_filename;
- int result;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- old_filename = (*env)->GetStringUTFChars (env, t, 0);
- if (old_filename == NULL)
- {
- return 0;
- }
- new_filename = (*env)->GetStringUTFChars (env, d, 0);
- if (new_filename == NULL)
- {
- (*env)->ReleaseStringUTFChars (env, t, old_filename);
- return 0;
- }
- result = cpio_rename (old_filename, new_filename);
- (*env)->ReleaseStringUTFChars (env, d, new_filename);
- (*env)->ReleaseStringUTFChars (env, t, old_filename);
- return (result == CPNATIVE_OK) ? 1 : 0;
- #else /* not WITHOUT_FILESYSTEM */
- return 0;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * This method returns an array of String representing all the files
- * in a directory except "." and "..".
- *
- * Class: java_io_VMFile
- * Method: list
- * Signature: (Ljava/lang/String;)[Ljava/lang/String;
- */
- JNIEXPORT jobjectArray JNICALL
- Java_java_io_VMFile_list (JNIEnv * env,
- jclass clazz __attribute__ ((__unused__)),
- jstring name)
- {
- #ifndef WITHOUT_FILESYSTEM
- const int REALLOC_SIZE = 10;
- const char *dirname;
- int result;
- char **filelist;
- void *handle;
- char *filename = (char *) JCL_malloc (env, FILENAME_MAX);
- unsigned long int filelist_count, max_filelist_count;
- char **tmp_filelist;
- jclass str_clazz;
- jobjectArray filearray;
- unsigned long int i;
- jstring str;
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- dirname = (*env)->GetStringUTFChars (env, name, 0);
- if (dirname == NULL)
- {
- return 0;
- }
- /* open directory for reading */
- result = cpio_openDir (dirname, &handle);
- (*env)->ReleaseStringUTFChars (env, name, dirname);
- if (result != CPNATIVE_OK)
- {
- return 0;
- }
- /* allocate filelist */
- filelist = (char **) JCL_malloc (env, sizeof (char *) * REALLOC_SIZE);
- if (filelist == NULL)
- {
- result = cpio_closeDir (handle);
- return 0;
- }
- filelist_count = 0;
- max_filelist_count = REALLOC_SIZE;
- /* read the files from the directory */
- result = cpio_readDir (handle, filename);
- while (result == CPNATIVE_OK)
- {
- if ((strcmp (filename, ".") != 0) && (strcmp (filename, "..") != 0))
- {
- /* allocate more memory if necessary */
- if (filelist_count >= max_filelist_count)
- {
- tmp_filelist = (char **) JCL_realloc (env,
- filelist,
- (max_filelist_count +
- REALLOC_SIZE) *
- sizeof (char *));
- if (tmp_filelist == NULL)
- {
- for (i = 0; i < filelist_count; i++)
- {
- JCL_free (env, filelist[i]);
- }
- JCL_free (env, filelist);
- result = cpio_closeDir (handle);
- return 0;
- }
- filelist = tmp_filelist;
- max_filelist_count += REALLOC_SIZE;
- }
- /* save entry in list (avoid strdup, because it is not ANSI C, thus difficult to port) */
- filelist[filelist_count] =
- (char *) JCL_malloc (env, strlen (filename) + 1);
- assert (filelist[filelist_count] != NULL);
- strcpy (filelist[filelist_count], filename);
- filelist_count++;
- }
- /* read next directory entry */
- result = cpio_readDir (handle, filename);
- }
- JCL_free (env, filename);
- /* close directory */
- result = cpio_closeDir (handle);
- /* put the list of files into a Java String array and return it */
- str_clazz = (*env)->FindClass (env, "java/lang/String");
- if (str_clazz == NULL)
- {
- for (i = 0; i < filelist_count; i++)
- {
- JCL_free (env, filelist[i]);
- }
- JCL_free (env, filelist);
- return 0;
- }
- filearray = (*env)->NewObjectArray (env, filelist_count, str_clazz, 0);
- if (filearray == NULL)
- {
- for (i = 0; i < filelist_count; i++)
- {
- JCL_free (env, filelist[i]);
- }
- JCL_free (env, filelist);
- return 0;
- }
- (*env)->DeleteLocalRef (env, str_clazz);
- for (i = 0; i < filelist_count; i++)
- {
- /* create new string */
- str = (*env)->NewStringUTF (env, filelist[i]);
- if (str == NULL)
- {
- /* We don't clean up everything here, but if this failed,
- something serious happened anyway */
- for (i = 0; i < filelist_count; i++)
- {
- JCL_free (env, filelist[i]);
- }
- JCL_free (env, filelist);
- return 0;
- }
- /* save into array */
- (*env)->SetObjectArrayElement (env, filearray, i, str);
- /* delete local reference */
- (*env)->DeleteLocalRef (env, str);
- }
- /* free resources */
- for (i = 0; i < filelist_count; i++)
- {
- JCL_free (env, filelist[i]);
- }
- JCL_free (env, filelist);
- return filearray;
- #else /* not WITHOUT_FILESYSTEM */
- return 0;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /*
- * These two methods are used to maintain dynamically allocated
- * buffers for getCanonicalPath without the overhead of calling
- * realloc every time a buffer is modified. Buffers are sized
- * at the smallest multiple of CHUNKSIZ that is greater than or
- * equal to the desired length. The default CHUNKSIZ is 256,
- * longer than most paths, so in most cases a getCanonicalPath
- * will require only one malloc per buffer.
- */
- #define CHUNKLOG 8
- #define CHUNKSIZ (1 << CHUNKLOG)
- static int
- nextChunkSize (int size)
- {
- return ((size >> CHUNKLOG) + ((size & (CHUNKSIZ - 1)) ? 1 : 0)) << CHUNKLOG;
- }
- static char *
- maybeGrowBuf (JNIEnv *env, char *buf, int *size, int required)
- {
- if (required > *size)
- {
- *size = nextChunkSize (required);
- buf = JCL_realloc (env, buf, *size);
- }
- return buf;
- }
- /*************************************************************************/
- /*
- * This method converts a path to canonical form on GNU/Posix systems.
- * This involves the removal of redundant separators, references to
- * "." and "..", and symbolic links.
- *
- * The conversion proceeds on a component-by-component basis: symbolic
- * links and references to ".." are resolved as and when they occur.
- * This means that if "/foo/bar" is a symbolic link to "/baz" then the
- * canonical form of "/foo/bar/.." is "/" and not "/foo".
- *
- * In order to mimic the behaviour of proprietary JVMs, non-existant
- * path components are allowed (a departure from the normal GNU system
- * convention). This means that if "/foo/bar" is a symbolic link to
- * "/baz", the canonical form of "/non-existant-directory/../foo/bar"
- * is "/baz".
- *
- * Class: java_io_VMFile
- * Method: toCanonicalForm
- * Signature: (Ljava/lang/String)Ljava/lang/String
- */
- JNIEXPORT jstring JNICALL
- Java_java_io_VMFile_toCanonicalForm (JNIEnv *env,
- jclass class __attribute__ ((__unused__)),
- jstring jpath)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *path;
- char *src, *dst;
- int srci, dsti;
- int srcl, dstl;
- int len;
- int fschecks;
- #if defined (HAVE_LSTAT) && defined (HAVE_READLINK)
- struct stat sb;
- #endif /* HAVE_LSTAT && HAVE_READLINK */
- path = JCL_jstring_to_cstring (env, jpath);
- if (path == NULL)
- return NULL;
- /* It is the caller's responsibility to ensure the path is absolute. */
- if (path[0] == 0 || path[0] != '/')
- {
- JCL_free_cstring (env, jpath, path);
- JCL_ThrowException (env, "java/lang/RuntimeException", "Not absolute");
- return NULL;
- }
- len = strlen (path);
- srcl = nextChunkSize (len + 1);
- src = JCL_malloc (env, srcl);
- if (src == NULL)
- {
- JCL_free_cstring (env, jpath, path);
- return NULL;
- }
- strcpy (src, path);
- JCL_free_cstring (env, jpath, path);
- srci = 1;
- dstl = nextChunkSize (2);
- dst = JCL_malloc (env, dstl);
- if (dst == NULL)
- {
- JCL_free (env, src);
- return NULL;
- }
- dst[0] = '/';
- dsti = 1;
- fschecks = JNI_TRUE;
- while (src[srci] != '\0')
- {
- int tmpi, dsti_save;
- /* Skip slashes. */
- while (src[srci] == '/')
- srci++;
- tmpi = srci;
- /* Find next slash. */
- while (src[srci] != '/' && src[srci] != '\0')
- srci++;
- if (srci == tmpi)
- /* We hit the end. */
- break;
- len = srci - tmpi;
- /* Handle "." and "..". */
- if (len == 1 && src[tmpi] == '.')
- continue;
- if (len == 2 && src[tmpi] == '.' && src[tmpi + 1] == '.')
- {
- while (dsti > 1 && dst[dsti - 1] != '/')
- dsti--;
- if (dsti != 1)
- dsti--;
- /* Reenable filesystem checking if disabled, as we might
- * have reversed over whatever caused the problem before.
- * At least one proprietary JVM has inconsistencies because
- * it does not do this.
- */
- fschecks = JNI_TRUE;
- continue;
- }
- /* Handle real path components. */
- dst = maybeGrowBuf (env,
- dst, &dstl, dsti + (dsti > 1 ? 1 : 0) + len + 1);
- if (dst == NULL)
- {
- JCL_free (env, src);
- return NULL;
- }
- dsti_save = dsti;
- if (dsti > 1)
- dst[dsti++] = '/';
- strncpy (&dst[dsti], &src[tmpi], len);
- dsti += len;
- if (fschecks == JNI_FALSE)
- continue;
- #if defined (HAVE_LSTAT) && defined (HAVE_READLINK)
- dst[dsti] = '\0';
- if (lstat (dst, &sb) == 0)
- {
- if (S_ISLNK (sb.st_mode))
- {
- int tmpl = CHUNKSIZ;
- char *tmp = JCL_malloc (env, tmpl);
- if (tmp == NULL)
- {
- JCL_free (env, src);
- JCL_free (env, dst);
- return NULL;
- }
- while (1)
- {
- tmpi = readlink (dst, tmp, tmpl);
- if (tmpi < 1)
- {
- JCL_free (env, src);
- JCL_free (env, dst);
- JCL_free (env, tmp);
- JCL_ThrowException (env, "java/io/IOException",
- "readlink failed");
- return NULL;
- }
- if (tmpi < tmpl)
- break;
- tmpl += CHUNKSIZ;
- tmp = JCL_realloc (env, tmp, tmpl);
- }
- /* Prepend the link's path to src. */
- tmp = maybeGrowBuf (env,
- tmp, &tmpl, tmpi + strlen (&src[srci]) + 1);
- if (tmp == NULL)
- {
- JCL_free (env, src);
- JCL_free (env, dst);
- return NULL;
- }
- strcpy (&tmp[tmpi], &src[srci]);
- JCL_free (env, src);
- src = tmp;
- srcl = tmpl;
- srci = 0;
- /* Either replace or append dst depending on whether the
- * link is relative or absolute.
- */
- dsti = src[0] == '/' ? 1 : dsti_save;
- }
- }
- else
- {
- /* Something doesn't exist, or we don't have permission to
- * read it, or a previous path component is a directory, or
- * a symlink is looped. Whatever, we can't check the
- * filesystem any more.
- */
- fschecks = JNI_FALSE;
- }
- #endif /* HAVE_LSTAT && HAVE_READLINK */
- }
- dst[dsti] = '\0';
- jpath = (*env)->NewStringUTF (env, dst);
- JCL_free (env, src);
- JCL_free (env, dst);
- return jpath;
- #else /* not WITHOUT_FILESYSTEM */
- return NULL;
- #endif /* not WITHOUT_FILESYSTEM */
- }
- /*************************************************************************/
- /* ***** PRIVATE FUNCTIONS IMPLEMENTATION ***** */
- static jboolean set_file_permissions (JNIEnv *env, jstring name,
- jboolean enable,
- jboolean ownerOnly,
- int permissions)
- {
- #ifndef WITHOUT_FILESYSTEM
- const char *filename;
- int result = JNI_FALSE;
-
- /* Don't use the JCL convert function because it throws an exception
- on failure */
- filename = (*env)->GetStringUTFChars (env, name, 0);
- if (filename == NULL)
- {
- return JNI_FALSE;
- }
-
- if (ownerOnly)
- {
- permissions |= CPFILE_FLAG_USR;
- }
-
- if (!enable)
- {
- permissions |= CPFILE_FLAG_OFF;
- }
-
- result = cpio_chmod (filename, permissions);
- (*env)->ReleaseStringUTFChars (env, name, filename);
-
- return result == CPNATIVE_OK ? JNI_TRUE : JNI_FALSE;
-
- #else /* not WITHOUT_FILESYSTEM */
- return JNI_FALSE;
- #endif /* not WITHOUT_FILESYSTEM */
- }
|