aboutsummaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorronny2002-07-02 17:45:48 +0000
committerronny2002-07-02 17:45:48 +0000
commit1756b0a2eb3c90bc7782559fb0fc54ab8f7e3f2e (patch)
tree320701f85a69555fc95132e899896bd7931e4828 /main
parentRemoved object files. (diff)
Added cDirectory.c.
git-svn-id: https://svn.cs.ru.nl/repos/clean-compiler/trunk@1132 1f8540f1-abd5-4d5b-9d24-4c5ce8603e2d
Diffstat (limited to 'main')
-rw-r--r--main/Unix/cDirectory.c339
1 files changed, 339 insertions, 0 deletions
diff --git a/main/Unix/cDirectory.c b/main/Unix/cDirectory.c
new file mode 100644
index 0000000..b95f19b
--- /dev/null
+++ b/main/Unix/cDirectory.c
@@ -0,0 +1,339 @@
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "Clean.h"
+
+#ifndef NAME_MAX
+#define NAME_MAX 500
+#endif
+
+#define FALSE 0
+#define TRUE (!FALSE)
+
+// error codes:
+#define NoDirError 0
+#define OtherDirError -1
+#define DoesntExist -2
+#define BadName -3
+#define NotEnoughSpace -4
+#define AlreadyExists -5
+#define NoPermission -6
+#define MoveIntoOffspring -7
+#define MoveAcrossDisks -8
+#define NotYetRemovable -9
+
+uid_t gUserId;
+gid_t gGroupId;
+struct DIR *gpDir;
+struct dirent *gpDirent;
+struct stat gFileStat;
+char *gPath;
+int gPathLength;
+CleanStringVariable(gFileName,NAME_MAX+1);
+
+static int unix_error_to_clean_error(int errCode)
+{
+ switch(errCode) {
+ case ENOENT:
+ case ENOTDIR: return DoesntExist;
+ case ENAMETOOLONG: return BadName;
+ case EMLINK:
+ case ENOSPC: return NotEnoughSpace;
+ case EISDIR:
+ case EEXIST: return AlreadyExists;
+ case EPERM:
+ case EACCES:
+ case EROFS: return NoPermission;
+ case EINVAL: return MoveIntoOffspring;
+ case EXDEV: return MoveAcrossDisks;
+ case ENOTEMPTY: return NotYetRemovable;
+ default: return OtherDirError;
+ };
+}
+
+static int openSearch(const char *path, int length)
+{
+ int i;
+
+ gPathLength = length;
+ gPath = (char*) malloc(gPathLength+NAME_MAX+2);
+ if (!gPath) {
+ gpDir = NULL;
+ return 0;
+ }
+ else {
+ memcpy(gPath, path, gPathLength);
+ gPath[gPathLength] = '\0';
+ gpDir = (struct DIR*) opendir(gPath);
+ if (!gpDir)
+ return unix_error_to_clean_error(errno);
+ gPath[gPathLength] = '/'; // filename will be added later
+ gUserId = getuid();
+ gGroupId = getgid();
+ return NoDirError;
+ };
+}
+
+int findFirstFileC(CleanString cs_path)
+{
+ int errCode;
+
+ errCode = openSearch(CleanStringCharacters(cs_path), CleanStringLength(cs_path));
+ if (errCode)
+ return errCode;
+ else
+ return findNextFileC(0);
+}
+
+void getCommonFileInfoC(int also_get_file_name,
+ CleanString *pFileName, int *pFileSizeLow, int *pFileSizeHigh,
+ int *pYear, int *pMonth, int *pDay, int *pDayNr,
+ int *pHours, int *pMinutes, int *pSeconds,
+ int *pIsDirectory, int *pIsReadOnly)
+// requires gFileName and gFileStat to be initialized
+{
+ struct tm *pModificationTime;
+ int mask;
+ static int null = 0;
+
+ *pFileName = also_get_file_name ? (CleanString) gFileName : (CleanString) &null;
+ *pFileSizeLow = gFileStat.st_size;
+ *pFileSizeHigh = 0;
+ pModificationTime= localtime(&gFileStat.st_mtime);
+ *pYear = pModificationTime->tm_year+1900;
+ *pMonth = pModificationTime->tm_mon+1;
+ *pDay = pModificationTime->tm_mday;
+ *pDayNr = pModificationTime->tm_wday+1;
+ *pHours = pModificationTime->tm_hour;
+ *pMinutes = pModificationTime->tm_min;
+ *pSeconds = pModificationTime->tm_sec % 60;
+ *pIsDirectory = (gFileStat.st_mode & S_IFDIR) != 0;
+ mask = gUserId==gFileStat.st_uid ? S_IWUSR
+ : gGroupId==gFileStat.st_gid ? S_IWGRP
+ : S_IWOTH;
+ *pIsReadOnly = (gFileStat.st_mode & mask) == 0;
+}
+
+int findNextFileC(int dummy)
+// return values: 0=ok, 1=no further files in directory
+{
+ int i;
+
+ gpDirent = readdir((void*)gpDir);
+ if (!gpDirent)
+ return 1;
+
+ for(i=0; gpDirent->d_name[i]!='\0' && i<NAME_MAX; i++) {
+ CleanStringCharacters(gFileName)[i] = gpDirent->d_name[i];
+ gPath[gPathLength+1+i] = gpDirent->d_name[i];
+ };
+ CleanStringLength(gFileName)= i;
+ gPath[gPathLength+1+i] = '\0';
+ gFileStat.st_size = 0;
+ gFileStat.st_mode = 0;
+ lstat(gPath,&gFileStat);
+ return 0;
+}
+
+int getPlatformIdC(int dummy)
+{
+#define UnixPlatform 0
+ return UnixPlatform;
+}
+
+void getWindowsFileInfoC()
+{}
+
+
+void getMacFileInfoC()
+{}
+
+void getUnixFileInfoC(int *pModeBits, int *pOwnerUserId, int *pOwnerGroupId,
+ int *pLAYear, int *pLAMonth, int *pLADay, int *pLADayNr, // last access time
+ int *pLAHours, int *pLAMinutes, int *pLASeconds) // dito
+{
+ struct tm *pModificationTime;
+
+ *pModeBits = gFileStat.st_mode;
+ *pOwnerUserId = gFileStat.st_uid;
+ *pOwnerGroupId = gFileStat.st_gid;
+ pModificationTime= localtime(&gFileStat.st_atime);
+ *pLAYear = pModificationTime->tm_year+1900;
+ *pLAMonth = pModificationTime->tm_mon+1;
+ *pLADay = pModificationTime->tm_mday;
+ *pLADayNr = pModificationTime->tm_wday+1;
+ *pLAHours = pModificationTime->tm_hour;
+ *pLAMinutes = pModificationTime->tm_min;
+ *pLASeconds = pModificationTime->tm_sec % 60;
+}
+
+
+void closeSearchC()
+{
+ free(gPath);
+ if (gpDir)
+ closedir((void*)gpDir);
+}
+
+int findSingleFileC(CleanString cs_path)
+{
+ int err,i,length;
+ char *path_chars;
+
+ gFileStat.st_size = 0;
+ gFileStat.st_mode = 0;
+
+ path_chars = CleanStringCharacters(cs_path);
+ if (lstat(path_chars,&gFileStat))
+ return unix_error_to_clean_error(errno);
+
+ i = CleanStringLength(cs_path)-2;
+ while (i>=0 && path_chars[i]!='/')
+ i--;
+ // the last path element ranges from path_chars[i+1] to path_chars[CleanStringLength(cs_path)-2]
+
+ length = CleanStringLength(cs_path)-2-i;
+ CleanStringLength(gFileName) = length;
+ memcpy(CleanStringCharacters(gFileName), path_chars+i+1, length);
+
+ return NoDirError;
+}
+
+void closeSingleSearchC()
+{}
+
+int createDirectoryC(CleanString cs_path)
+{
+ int err;
+
+ err = mkdir(CleanStringCharacters(cs_path),
+ S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+ // access rights for newly created directory: rwx--x--x
+ if (err)
+ return unix_error_to_clean_error(errno);
+ else
+ return NoDirError;
+}
+
+int fremoveC(CleanString cs_path)
+{
+ int err;
+
+ err = remove(CleanStringCharacters(cs_path));
+ if (err) {
+ if (errno==EEXIST)
+ return NotYetRemovable;
+ else
+ return unix_error_to_clean_error(errno);
+ }
+ else
+ return NoDirError;
+}
+
+// Try this code with slackware linux, if the testLinux program doesn't work
+//int fremoveC(CleanString cs_path)
+//{
+// int err;
+//
+// err = unlink(CleanStringCharacters(cs_path));
+// if (err) {
+// if (errno==EPERM) {
+// err = rmdir(CleanStringCharacters(cs_path));
+// if (err)
+// return unix_error_to_clean_error(errno);
+// else
+// return NoDirError;
+// }
+// else
+// return unix_error_to_clean_error(errno);
+// }
+// else
+// return NoDirError;
+//}
+
+#define OK 0
+#define STRING_TOO_SMALL 1
+
+int getCurrentDirectory_SE(CleanString cs)
+{
+ if (getcwd(CleanStringCharacters(cs), CleanStringLength(cs))) {
+ // success. convert C String to Clean string
+ int i;
+ i = 0;
+ while(CleanStringCharacters(cs)[i]!='\0')
+ i++;
+ CleanStringLength(cs) = i;
+ return OK;
+ }
+ else {
+ // failure
+ if (errno==EACCES) {
+ // the permission to read the current directory was denied (how ever)
+ // return root directory
+ CleanStringLength(cs) = 1;
+ CleanStringCharacters(cs)[0] = '/';
+ return OK;
+ }
+ else
+ return STRING_TOO_SMALL;
+ };
+}
+
+void get_mac_dir_parent_and_name_C()
+{
+}
+
+int setCurrentDirectoryC(CleanString csPath)
+{
+ int err;
+
+ err = chdir(CleanStringCharacters(csPath));
+ if (err)
+ return unix_error_to_clean_error(errno);
+ else
+ return NoDirError;
+}
+
+void getMacDiskNameC()
+{}
+
+void get_windows_disk_available_bits_C()
+{}
+
+void macRenameC()
+{}
+
+void macMoveC()
+{}
+
+int fmoveC(int overwrite, CleanString from, CleanString to)
+{
+ int err,clean_err;
+
+ if (overwrite) {
+ err = rename(CleanStringCharacters(from), CleanStringCharacters(to));
+ if (err && errno==ENOTDIR) {
+ // from is a directory and to a file
+ // try again after removing to
+ err = remove(CleanStringCharacters(to));
+ if (!err)
+ err = rename(CleanStringCharacters(from), CleanStringCharacters(to));
+ };
+ clean_err = err ? unix_error_to_clean_error(errno) : NoDirError;
+ }
+ else {
+ struct stat fileStat;
+ if (stat(CleanStringCharacters(to),&fileStat)) {
+ err = rename(CleanStringCharacters(from), CleanStringCharacters(to));
+ clean_err = err ? unix_error_to_clean_error(errno) : NoDirError;
+ }
+ else
+ clean_err = AlreadyExists;
+ };
+ return clean_err;
+}