This is sqUnixDirectory.c in view mode; [Download] [Up]
/* This file is a heavily modified version of the file "sqMacDicrectory.c". * * Modifications by: Ian Piumarta (ian.piumarta@inria.fr) * * The original version of this file can be regenerated from the Squeak * image by executing: * * InterpreterSupportCode writeMacSourceFiles * * $Log: sqUnixDirectory.c,v $ * Revision 1.1 1996/10/24 13:21:38 piumarta * Initial revision * */ static char rcsid[]= "$Id: sqUnixDirectory.c,v 1.1 1996/10/24 13:21:38 piumarta Exp piumarta $"; #include "sq.h" #ifdef NeXT #include <sys/dir.h> #define dirent direct #define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR)) #else #include <dirent.h> #endif #include <sys/param.h> #include <sys/types.h> #include <sys/stat.h> /*** The interface to the directory primitive is path based. That is, the client supplies a Squeak string describing the path to the directory on every call. To avoid traversing this path on every call, a cache is maintained of the last path seen, along with the Mac volume and folder reference numbers corresponding to that path. ***/ /*** Constants ***/ #define ENTRY_FOUND 0 #define NO_MORE_ENTRIES 1 #define BAD_PATH 2 #define DELIMITER '/' /*** Variables ***/ char lastPath[MAXPATHLEN+1]; int lastPathValid = false; int lastIndex; DIR *openDir; /*** Functions ***/ int convertToSqueakTime(int unixTime); int equalsLastPath(char *pathString, int pathStringLength); int recordPath(char *pathString, int pathStringLength, int refNum, int volNum); int maybeOpenDir(char *unixPath); int convertToSqueakTime(int unixTime) { /* Squeak epoch is Jan 1, 1901. Unix epoch is Jan 1, 1970: 17 leap years and 52 non-leap years later than Squeak. */ return (unsigned long)unixTime + ((52*365UL + 17*366UL) * 24*60*60UL); } int dir_Create(char *pathString, int pathStringLength) { /* Create a new directory with the given path. By default, this directory is created relative to the cwd. */ char name[1024]; int i; for (i = 0; i < pathStringLength; i++) name[i] = pathString[i]; name[i] = 0; /* string terminator */ return mkdir(name, 022) == 0; /* rwxr-xr-x */ } int dir_Delimitor(void) { return DELIMITER; } int dir_Lookup(char *pathString, int pathStringLength, int index, /* outputs: */ char *name, int *nameLength, int *creationDate, int *modificationDate, int *isDirectory, int *sizeIfFile) { /* Lookup the index-th entry of the directory with the given path, starting at the root of the file system. Set the name, name length, creation date, creation time, directory flag, and file size (if the entry is a file). Return: 0 if a entry is found at the given index 1 if the directory has fewer than index entries 2 if the given path has bad syntax or does not reach a directory */ int i; int nameLen= 0; struct dirent *dirEntry= 0; char unixPath[MAXPATHLEN+1]; struct stat statBuf; /* default return values */ *name = 0; *nameLength = 0; *creationDate = 0; *modificationDate = 0; *isDirectory = false; *sizeIfFile = 0; if ((pathStringLength == 0)) strcpy(unixPath, "."); else { for (i= 0; i < pathStringLength; i++) unixPath[i]= pathString[i]; unixPath[i]= 0; } /* get file or directory info */ if (!maybeOpenDir(unixPath)) { return BAD_PATH; } if (++lastIndex == index) index= 1; /* fake that the dir is rewound and we want the first entry */ else rewinddir(openDir); /* really rewind it, and read to the index */ for (i= 0; i < index; i++) { nextEntry: dirEntry= readdir(openDir); if (!dirEntry) { return NO_MORE_ENTRIES; } #ifdef HAS_D_NAMLEN nameLen= dirEntry->d_namlen; #else nameLen= strlen(dirEntry->d_name); #endif /* ignore '.' and '..' (these are not *guaranteed* to be first) */ if (nameLen < 3 && dirEntry->d_name[0] == '.') if (nameLen == 1 || dirEntry->d_name[1] == '.') goto nextEntry; } strncpy(name, dirEntry->d_name, nameLen); *nameLength= nameLen; { char terminatedName[MAXPATHLEN]; strncpy(terminatedName, dirEntry->d_name, nameLen); terminatedName[nameLen]= '\0'; strcat(unixPath, "/"); strcat(unixPath, terminatedName); if (stat(unixPath, &statBuf) && lstat(unixPath, &statBuf)) { return BAD_PATH; } } /* use modification time instead (just like ls) */ *creationDate= convertToSqueakTime(statBuf.st_mtime); /* use status change time instead */ *modificationDate= convertToSqueakTime(statBuf.st_ctime); if (S_ISDIR(statBuf.st_mode)) *isDirectory= true; else *sizeIfFile= statBuf.st_size; return ENTRY_FOUND; } int maybeOpenDir(char *unixPath) { /* if the last opendir was to the same directory, re-use the directory pointer from last time. Otherwise close the previous directory, open the new one, and save its name. Return true if the operation was successful, false if not. */ if (!lastPathValid || strcmp(lastPath, unixPath)) { /* invalidate the old, open the new */ if (lastPathValid) closedir(openDir); lastPathValid= false; strcpy(lastPath, unixPath); if ((openDir= opendir(unixPath)) == 0) return false; lastPathValid= true; lastIndex= 0; /* first entry is index 1 */ } return true; } int dir_SetMacFileTypeAndCreator(char *filename, int filenameSize, char *fType, char *fCreator) { /* unix files are untyped, and the creator is correct by default */ return true; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.