int prDirectory_At(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a = g->sp - 2; PyrSlot *b = g->sp - 1; PyrSlot *c = g->sp; PyrSlot *dirPathSlot = slotRawObject(a)->slots + 0; int err, index; err = slotIntVal(c, &index); if (err) { SetNil(a); return err; } char name[256], fullPathName[256]; int nameLength, creationDate, modificationDate, isDirectory, isVisible, sizeIfFile; int dirPathLength = slotRawObject(dirPathSlot)->size; err = dir_Lookup(slotRawObject(dirPathSlot)s->s, dirPathLength, index+1, name, &nameLength, &creationDate, &modificationDate, &isDirectory, &isVisible, &sizeIfFile); if (err == 1) { SetNil(a); return errNone; } if (err) { error("Invalid path\n"); SetNil(a); return errFailed; } if (dirPathLength + nameLength + 1 > 255) { error("Full path name too long.\n"); SetNil(a); return errFailed; } PyrSlot *entryName = slotRawObject(b)->slots + 0; PyrSlot *entryPath = slotRawObject(b)->slots + 1; PyrSlot *entryIsDir = slotRawObject(b)->slots + 2; PyrSlot *entryIsVisible = slotRawObject(b)->slots + 3; PyrString *nameString = newPyrString(g->gc, name, 0, true); SetObject(entryName, nameString); g->gc->GCWrite(slotRawObject(b), (PyrObject*)nameString); memcpy(fullPathName, slotRawObject(dirPathSlot)s->s, dirPathLength); fullPathName[dirPathLength] = DELIMITOR; strcpy(fullPathName + dirPathLength + 1, name); PyrString *pathString = newPyrString(g->gc, fullPathName, 0, true); SetObject(entryPath, pathString); g->gc->GCWrite(slotRawObject(b), (PyrObject*)pathString); if (isDirectory) { SetTrue(entryIsDir); } else { SetFalse(entryIsDir); } if (isVisible) { SetTrue(entryIsVisible); } else { SetFalse(entryIsVisible); } slotCopy(a,b); return errNone; }
primitiveDirectoryLookup(void) { sqInt createDate; sqInt dirFlag; char entryName[256]; sqInt entryNameSize; squeakFileOffsetType fileSize; sqInt index; sqInt modifiedDate; sqInt okToList; sqInt pathName; char *pathNameIndex; sqInt pathNameSize; sqInt status; index = interpreterProxy->stackIntegerValue(0); pathName = interpreterProxy->stackValue(1); if (!(interpreterProxy->isBytes(pathName))) { return interpreterProxy->primitiveFail(); } pathNameIndex = interpreterProxy->firstIndexableField(pathName); /* If the security plugin can be loaded, use it to check for permission. If not, assume it's ok */ pathNameSize = interpreterProxy->byteSizeOf(pathName); if (sCLPfn != 0) { okToList = ((sqInt (*)(char *, sqInt))sCLPfn)(pathNameIndex, pathNameSize); } else { okToList = 1; } if (okToList) { status = dir_Lookup(pathNameIndex, pathNameSize, index, entryName, &entryNameSize, &createDate, &modifiedDate, &dirFlag, &fileSize); } else { status = DirNoMoreEntries; } if (interpreterProxy->failed()) { return null; } if (status == DirNoMoreEntries) { interpreterProxy->popthenPush(3, interpreterProxy->nilObject()); return null; } if (status == DirBadPath) { return interpreterProxy->primitiveFail(); } interpreterProxy->popthenPush(3, makeDirEntryNamesizecreateDatemodDateisDirfileSize(entryName, entryNameSize, createDate, modifiedDate, dirFlag, fileSize)); }
primitiveDirectoryLookup(void) { // FilePlugin>>#primitiveDirectoryLookup sqInt createDate; sqInt dirFlag; char entryName[256]; sqInt entryNameSize; squeakFileOffsetType fileSize; sqInt index; sqInt modifiedDate; sqInt okToList; sqInt pathName; char *pathNameIndex; sqInt pathNameSize; sqInt posixPermissions; sqInt status; sqInt symlinkFlag; index = stackIntegerValue(0); pathName = stackValue(1); if (!(isBytes(pathName))) { return primitiveFail(); } pathNameIndex = firstIndexableField(pathName); /* If the security plugin can be loaded, use it to check for permission. If not, assume it's ok */ pathNameSize = byteSizeOf(pathName); if (sCLPfn != 0) { okToList = ((sqInt (*)(char *, sqInt))sCLPfn)(pathNameIndex, pathNameSize); } else { okToList = 1; } if (okToList) { status = dir_Lookup( pathNameIndex, pathNameSize, index, entryName, &entryNameSize, &createDate, &modifiedDate, &dirFlag, &fileSize, &posixPermissions, &symlinkFlag); } else { status = DirNoMoreEntries; } if (failed()) { return null; } if (status == DirNoMoreEntries) { /* no more entries; return nil */ /* pop pathName, index, rcvr */ popthenPush(3, nilObject()); return null; } if (status == DirBadPath) { return primitiveFail(); } popthenPush(3, makeDirEntryNamesizecreateDatemodDateisDirfileSizeposixPermissionsisSymlink(entryName, entryNameSize, createDate, modifiedDate, dirFlag, fileSize, posixPermissions, symlinkFlag)); }