addSlotValue(f, ru, gCoreVocab->RDF_parent, f->top, RDF_RESOURCE_TYPE, 1);
addSlotValue(f, ru, gCoreVocab->RDF_parent, f->top, RDF_RESOURCE_TYPE, NULL);
parseNextESFTPLine (RDFFile f, char* line){	PRBool		directoryp;	RDF_Resource	ru;	char		*token, *url;	int16		loop, tokenNum = 0;	int32		val;	if (f->fileType != FTP_RT && f->fileType != ES_RT)	return;	/* work around bug where linefeeds are actually encoded as %0A */	if (endsWith("%0A", line))	line[strlen(line)-3] = '\0';	if ((token = strtok(line, " ")) != NULL)	{		/* skip 1st token (the numeric command) */		token = strtok(NULL, " \t");	}	if (startsWith("200:", line))	{		while (token != NULL)		{			while ((token != NULL) && (tokenNum < RDF_MAX_NUM_FILE_TOKENS))			{				if (!strcmp(token, "Filename"))				{					f->tokens[f->numFileTokens].token = gCoreVocab->RDF_name;					f->tokens[f->numFileTokens].type = RDF_STRING_TYPE;					f->tokens[f->numFileTokens].tokenNum = tokenNum;					++(f->numFileTokens);				}				else if (!strcmp(token, "Content-Length"))				{					f->tokens[f->numFileTokens].token = gWebData->RDF_size;					f->tokens[f->numFileTokens].type = RDF_INT_TYPE;					f->tokens[f->numFileTokens].tokenNum = tokenNum;					++(f->numFileTokens);				}				else if (!strcmp(token, "File-type"))				{					f->tokens[f->numFileTokens].token = gWebData->RDF_description;					f->tokens[f->numFileTokens].type = RDF_STRING_TYPE;					f->tokens[f->numFileTokens].tokenNum = tokenNum;					++(f->numFileTokens);				}				else if (!strcmp(token, "Last-Modified"))				{					f->tokens[f->numFileTokens].token = gWebData->RDF_lastModifiedDate;					f->tokens[f->numFileTokens].type = RDF_STRING_TYPE;					f->tokens[f->numFileTokens].tokenNum = tokenNum;					++(f->numFileTokens);				}/*				else if (!strcmp(token, "Permissions"))				{					f->tokens[f->numFileTokens].token = NULL;					f->tokens[f->numFileTokens].type = RDF_STRING_TYPE;					f->tokens[f->numFileTokens].tokenNum = tokenNum;					++(f->numFileTokens);				}*/				++tokenNum;				token = strtok(NULL, " \t");			}		}	}	else if (startsWith("201:", line))	{		directoryp = false;		while (token != NULL)		{			for (loop=0; loop<f->numFileTokens; loop++)			{				if (tokenNum == f->tokens[loop].tokenNum)				{					f->tokens[loop].data = strdup(token);					if (f->tokens[loop].token == gWebData->RDF_description)					{						if (startsWith("Directory", token) ||							startsWith("Sym-Directory", token))						{							directoryp = true;						}					}				}			}			++tokenNum;			token = strtok(NULL, " \t");		}		ru = NULL;		for (loop=0; loop<f->numFileTokens; loop++)		{			/* find name, create resource from it */			if (f->tokens[loop].token == gCoreVocab->RDF_name)			{				if (resourceType(f->top) == ES_RT)				{					url = PR_smprintf("nes:%s%s%s", f->url, f->tokens[loop].data, (directoryp) ? "/":"");				}				else				{					url = PR_smprintf("%s%s%s", f->url, f->tokens[loop].data, (directoryp) ? "/":"");				}				if (url != NULL)				{					if ((ru = RDF_GetResource(NULL, url, 1)) != NULL)					{						setResourceType(ru, resourceType(f->top));						if (directoryp == true)							{							setContainerp(ru, 1);						}					XP_FREE(url);					}				}				break;							}		}		if (ru != NULL)		{			for (loop=0; loop<f->numFileTokens; loop++)			{				if (f->tokens[loop].data != NULL)				{					switch(f->tokens[loop].type)					{						case	RDF_STRING_TYPE:						addSlotValue(f, ru, f->tokens[loop].token,							unescapeURL(f->tokens[loop].data),							f->tokens[loop].type, 1);						break;							case	RDF_INT_TYPE:						if (directoryp == false)						{							sscanf(f->tokens[loop].data, "%lu", &val);							if (val != 0)							{								addSlotValue(f, ru, f->tokens[loop].token,									(void *)val, f->tokens[loop].type, 1);							}						}						break;					}				}			}			addSlotValue(f, ru, gCoreVocab->RDF_parent, f->top, RDF_RESOURCE_TYPE, 1);		}			}}