This is FtpDirectory.m in view mode; [Download] [Up]
#import "FtpDirectory.h"
#import "FtpBrowserCell.h"
#import "SortedList.h"
#import "FtpSession.h"
#import "FtpConnection.h"
#import "NXmystd.h"
#define UPDATETIMEOUT (60*60*24) // 1 day
//#define UPDATETIMEOUT (60*60*3) // 3 hours
//#define UPDATETIMEOUT 30
#define FORCEDUPDATETIMEOUT (60*60*24*14) // 2 weeks
@implementation FtpDirectory
- initForName:(const char *)name withParent:aParent;
{
id dummyFile;
[super initForName:name withParent:aParent];
if (parent)
{
NXAtom parentpath = [parent path];
char *buf;
buf = calloc(strlen(parentpath)+strlen(myname)+50,sizeof(char));
if (strcmp(parentpath,"/")==0)
parentpath = "";
sprintf(buf,"%s/%s",parentpath,name);
mypath = NXUniqueString(buf);
free(buf);
}
else
{
mypath = NXUniqueString("/");
}
list = [[SortedList alloc] init];
updateTmpList = [[SortedList alloc] init];
isBeingUpdated = FALSE;
dummyFile = [[FtpFile alloc] initForName:"not loaded" withParent:self];
[dummyFile setDummy];
[dummyFile setNew:NO];
[list addObject:dummyFile];
needsDisplay = YES;
needsUpdate = YES;
firstUpdate = YES;
firstUpdateDisplay = NO;
neededUpdate = [self needsUpdate]+2*[self needsCheck];
statusString = NXUniqueString("");
shouldTransfer = NO;
return self;
}
- free; // should test for isBeingUpdated...
{
[list freeObjects];
list = [list free];
updateTmpList = [updateTmpList free];
return [super free];
}
- write:(NXTypedStream *)stream;
{
id saveList = isBeingUpdated?cacheHelpList:list;
[FtpDirectory setVersion:0];
[super write:stream];
if ([Object version] != 4)
{
NXWriteTypes(stream, "@cc%", &saveList, &firstUpdate, &firstUpdateDisplay, &statusString);
}
else
{
// for default cache (version 4)
NXWriteTypes(stream, "@cc", &saveList, &firstUpdate, &firstUpdateDisplay);
}
return self;
}
- read:(NXTypedStream *)stream;
{
[super read:stream];
if ([Object version] >= 5)
{
NXReadTypes(stream, "@cc%", &list, &firstUpdate, &firstUpdateDisplay, &statusString);
mypath = NULL;
}
else if ([Object version] >= 4)
{
NXReadTypes(stream, "@cc", &list, &firstUpdate, &firstUpdateDisplay);
statusString = NXUniqueString("");
mypath = NULL;
}
else if ([Object version] >= 2)
{
NXReadTypes(stream, "%@cc%", &mypath, &list, &firstUpdate, &firstUpdateDisplay, &statusString);
}
else
{
NXReadTypes(stream, "%@cc", &mypath, &list, &firstUpdate, &firstUpdateDisplay);
statusString = NXUniqueString("");
mypath = NULL;
}
if ([Object version] < 3)
{
timestamp = 0;
}
return self;
}
- awake;
{
[super awake];
neededUpdate = 0;
isBeingUpdated = NO;
needsUpdate = NO;
needsDisplay = YES;
updateTmpList = [[SortedList alloc] init];
cacheHelpList = nil;
shouldTransfer = 0;
[self setPathAfterAwake];
return self;
}
- setPathAfterAwake;
{
if (!mypath)
{
if (parent)
{
NXAtom parentpath = [parent path];
char *buf;
if (!parentpath)
{
[parent setPathAfterAwake];
parentpath = [parent path];
if (!parentpath)
{
NXBeep();
ERRORF("ERROR: parentpath == NULL");
parentpath = NXUniqueString("/");
}
}
//LOGF("name = %s,parentpath = %s",myname,parentpath);
buf = calloc(strlen(parentpath)+strlen(myname)+50,sizeof(char));
if (strcmp(parentpath,"/")==0)
parentpath = "";
sprintf(buf,"%s/%s",parentpath,myname);
mypath = NXUniqueString(buf);
free(buf);
//LOGF("name = %s,parentpath = %s,mypath = %s",myname,parentpath,mypath);
}
else
{
mypath = NXUniqueString("/");
//LOGF("Im the root");
}
}
return self;
}
- getObjWithName:(char *)s
{
NXAtom name = NXUniqueString(s);
int i;
id obj;
for (i=0;i<[list count];i++)
{
obj = [list objectAt:i];
if (name == [obj name])
return obj;
}
return nil;
}
- getDirWithName:(char *)s;
{
id obj = [self getObjWithName:s];
if (obj && [obj isDir])
return obj;
else
return nil;
}
- getFileWithName:(char *)s;
{
id obj = [self getObjWithName:s];
if (obj && [obj isFile])
return obj;
else
return nil;
}
- (int) fillMatrix:matrix;
{
int i,numcells;
//int rows,cols;
id cell,obj;
static List *selList = NULL;
static NXStringTable *strings = NULL;
if (!selList || strings)
{
selList = [[List alloc] init];
strings = [[NXStringTable alloc] init];
}
//LOGF("start %s",mypath);
needsDisplay = FALSE;
[selList empty];
[strings empty];
[matrix getSelectedCells:selList];
for (i=0;i<[selList count];i++)
{
[strings insertKey:NXUniqueString([[selList objectAt:i] stringValue]) value:"faslebla"];
//LOGF("added name %s",[[selList objectAt:i] stringValue]);
}
//[[matrix cellList] makeObjectsPerform:@selector(setFile:) with:nil];
[matrix selectCellAt:-1:-1];
[matrix clearSelectedCell];
[matrix renewRows:0 cols:1];
//LOGF("mitte %s",mypath);
for (i=0;i<[list count];i++)
{
obj = [list objectAt:i];
cell = [matrix cellAt:i:0];
//printf("cell = %p,i=%d\n",cell,i);
if ( ! cell )
{
[matrix insertRowAt:i];
cell = [matrix cellAt:i:0];
//printf("new cell = %p,i=%d\n",cell,i);
}
[cell setStringValue:[obj name]];
[cell setFileSize:[obj fileSize]];
[cell setLeaf:[obj isFile]];
[cell setEnabled: ! [obj isDummy]];
[cell setLoaded:YES];
[cell setNew:[obj isNew]];
[cell setFile:obj];
//[cell setState:[obj isSelected]];
if ([strings isKey:[cell stringValue]])
{
//LOGF("selecting name %s",[cell stringValue]);
//[matrix setState:1 at:i:0];
//[matrix selectCellAt:i:0]; // selectCellAt:: REMOVES prev. selections !
[matrix setSelectionFrom:i to:i anchor:i lit:YES]; // and this one doesnt (isn't it great !!!) !!
}
//else
// [matrix setState:0 at:i:0];
[cell setParentNeedsUpdate:[self needsCheck]&&![obj isDummy]];
if ([obj isDir])
{
[cell setNeedsCheck:[obj needsCheck]];
[cell setNeedsUpdate:[obj needsUpdate]];
[cell setNeedsFirstUpdate:[obj needsFirstUpdate]];
}
}
numcells = i;
if (firstUpdateDisplay)
{
needsDisplay = YES;
firstUpdateDisplay = NO;
}
#ifdef DEBUG
[matrix getSelectedCells:[selList empty]];
for (i=0;i<[selList count];i++)
{
//LOGF("selected: %s",[[selList objectAt:i] stringValue]);
}
#endif
[matrix sizeToCells];
[matrix display];
//LOGF("ende %s",mypath);
return numcells;
}
- addSubDirsToCheckTo:con;
{
int i;
for (i=0;i<[list count];i++)
{
id dir = [list objectAt:i];
if ([dir isDir])
{
if ([dir needsCheck] && ![dir needsFirstUpdate])
{
[con addToQueue:dir];
//LOGF("dir needsCheck:%s",[dir name]);
}
}
}
return self;
}
- beginUpdate;
{
//printf("dir:%s beginUpdate\n",mypath);
isBeingUpdated = YES;
cacheHelpList = [list copy];
[updateTmpList free];
updateTmpList = [list copy];
return self;
}
- update:(char *)s withSize:(long)size isFile:(BOOL)isFile;
{
id obj;
id class;
//printf("dir: |%s|\n",s);
obj = [self getObjWithName:s];
if (!isBeingUpdated)
return nil;
if ( obj && [obj isFile] == isFile ) // new obj is already there
{
[obj setNew:NO];
if ([obj fileSize] != size)
{
if ([obj fileSize] != -1)
[obj setNew:YES];
[obj setFileSize:size];
}
[updateTmpList removeObject:obj];
return obj;
}
else if (obj) // file <--> dir
{
[list removeObject:obj];
[updateTmpList removeObject:obj];
[cacheHelpList removeObject:obj];
obj = [obj free];
}
if (isFile)
class = [FtpFile class];
else
class = [FtpDirectory class];
obj = [[class alloc] initForName:NXUniqueString(s) withParent:self];
if (firstUpdate)
[obj setNew:NO];
[obj setFileSize:size];
return [self add:obj];
}
- endUpdate;
{
int i;
//printf("dir:%s endUpdate\n",mypath);
timestamp = time(0);
shouldTransfer = 0;
needsUpdate = NO;
if (!isBeingUpdated)
return self;
if (firstUpdate)
{
firstUpdate = NO;
firstUpdateDisplay = YES;
}
needsDisplay = YES;
[parent setNeedsDisplay:YES];
for (i=0;i < [updateTmpList count];i++)
{
[list removeObject:[updateTmpList objectAt:i]];
}
//[updateTmpList freeObjects];
isBeingUpdated = NO;
cacheHelpList = [cacheHelpList free];
return self;
}
- add:obj;
{
if ( [obj isFile] || [obj isDir] )
{
timestamp++;
[list addObjectSorted:obj];
return obj;
}
else
return nil;
}
- remove:obj;
{
if ( [obj isFile] || [obj isDir] )
{
if ([list removeObject:obj])
return self;
else
return nil;
}
else
return nil;
}
- (BOOL) needsCheck;
{
if (difftime (time(0), timestamp) > UPDATETIMEOUT)
return YES;
else
return NO;
}
- (BOOL) needsUpdate;
{
return needsUpdate|firstUpdate|(difftime (time(0), timestamp) > FORCEDUPDATETIMEOUT);
}
- setNeedsNoUpdate;
{
timestamp = time(0);
return self;
}
- setNeedsUpdate;
{
needsUpdate = YES;
return self;
}
- (BOOL) needsFirstUpdate;
{
return firstUpdate;
}
- (const char *) path;
{
//printf("FtpDirectory:|%s| path=|%s|\n",myname,mypath);
return mypath;
}
- setStatusString:(const char *)s;
{
//LOGF("%s:\nstatus:|%s|",mypath,s);
statusString = NXUniqueString(s);
return self;
}
- (BOOL)compareStatusString:(const char *)s;
{
LOGF("%s:\noldStatus:|%s|\nnewStatus:|%s|\nisEqual: %s",mypath,statusString,s,(NXUniqueString(s) == statusString)?"YES":"NO");
return (NXUniqueString(s) == statusString)?TRUE:FALSE;
}
- setShouldTransferIfNeeded;
{
if (shouldTransfer < 1)
shouldTransfer = 1;
return self;
}
- setShouldTransferAlways;
{
if (shouldTransfer < 2)
shouldTransfer = 2;
return self;
}
- (BOOL)shouldTransferIfNeeded;
{
return shouldTransfer > 0;
}
- (BOOL)shouldTransferAlways;
{
return shouldTransfer > 1;
}
- (BOOL) isFile;
{
return NO;
}
- (BOOL) isDir;
{
return YES;
}
- (BOOL)isDummy;
{
return NO;
}
- (BOOL) needsDisplay;
{
BOOL flag = NO;
if (neededUpdate != [self needsUpdate]+2*[self needsCheck])
flag = YES;
neededUpdate = [self needsUpdate]+2*[self needsCheck];
flag|=needsDisplay;
needsDisplay = NO;
return flag;
}
- setNeedsDisplay:(BOOL)flag;
{
needsDisplay = flag;
return self;
}
// by Peter Lount
- fullPath:(char*)theFullPathPtr;
{
sprintf(theFullPathPtr,
"%s",[self path]
);
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.