Example #1
0
void app_sig_for_pathname(const char * path, BString * signature) 
{
	*signature = ZK_APP_SIG;

	BNode node (path);
	attr_info info;
	char buffer [B_MIME_TYPE_LENGTH];
	if (node.GetAttrInfo("BEOS:APP_SIG", & info) == B_OK)
	{
		PRINT(("node.GetAttrInfo(BEOS:APP_SIG, & info) == B_OK\n"));
	
		if (node.ReadAttr("BEOS:APP_SIG", info.type, 0, & buffer, info.size) == info.size)
		{
			PRINT(("node.ReadAttr(BEOS:APP_SIG, info.type, 0, & buffer, info.size) == B_OK\n"));
			
			PRINT(("attribute: %s \n", buffer));
			*signature = buffer;
		}
		else
			PRINT(("No BEOS:APP_SIG attribute. Fallback to default.\n"));
	}
	else
		PRINT(("No BEOS:APP_SIG attribute. Fallback to default.\n"));		

}
Example #2
0
bool
ResourceData::SetFromAttribute(const char *name, BNode &node)
{
	attr_info info;
	if (node.GetAttrInfo(name, &info) != B_OK) {
		*this = ResourceData();
		return false;
	}
	
	fType = info.type;
	fID = -1;
	fIDString = "(attr)";
	fName = name;
	fLength = info.size;
	fAttr = true;

	fTypeString = MakeTypeString(fType);
	
	fData = (char *)malloc(fLength);
	if (fData) {
		ssize_t size = node.ReadAttr(name, info.type, 0, (void*)fData, fLength);
		if (size >= 0) {
			fLength = (size_t) size;
			return true;
		}
	}
	
	*this = ResourceData();
	return false;
}
/* copy atribytes */
bool
BF_GUI_FilesPanel_CopyTask::Copy_Atributes(BNode & o_NodeSrc,BNode & o_NodeDest)
{
    char 		pcName[B_ATTR_NAME_LENGTH];
    attr_info	uAttrInfo;
    uint32		iBufMaxSize=255;
    char		*pcBuf = (char*)malloc(iBufMaxSize);

    o_NodeSrc.RewindAttrs();
    //
    while(B_OK==o_NodeSrc.GetNextAttrName(pcName)) {
        if(B_OK==o_NodeSrc.GetAttrInfo(pcName,&uAttrInfo)) {
            /* check buffer size  */
            if(uAttrInfo.size>iBufMaxSize) {
                DELETE(pcBuf);
                iBufMaxSize = uAttrInfo.size;
                pcBuf = (char*)malloc(iBufMaxSize);
            }
            /* read attr */
            o_NodeSrc.ReadAttr(pcName,uAttrInfo.type,0,
                               (void*)pcBuf,uAttrInfo.size);
            /* write attr */
            o_NodeDest.WriteAttr(pcName,uAttrInfo.type,
                                 0,(void*)pcBuf,uAttrInfo.size);
            /* check for cancel_process */
            if(Canceled()) return false;
        }
    }
    DELETE(pcBuf);
    return true;
}/* end of atributes */
/*
 * this method is not currently being used, but it may be useful in the future...
 */
status_t
DefaultCatalog::ReadFromAttribute(const entry_ref &appOrAddOnRef)
{
	BNode node;
	status_t res = node.SetTo(&appOrAddOnRef);
	if (res != B_OK)
		return B_ENTRY_NOT_FOUND;

	attr_info attrInfo;
	res = node.GetAttrInfo(BLocaleRoster::kEmbeddedCatAttr, &attrInfo);
	if (res != B_OK)
		return B_NAME_NOT_FOUND;
	if (attrInfo.type != B_MESSAGE_TYPE)
		return B_BAD_TYPE;

	size_t size = attrInfo.size;
	auto_ptr<char> buf(new(std::nothrow) char [size]);
	if (buf.get() == NULL)
		return B_NO_MEMORY;
	res = node.ReadAttr(BLocaleRoster::kEmbeddedCatAttr, B_MESSAGE_TYPE, 0,
		buf.get(), size);
	if (res < (ssize_t)size)
		return res < B_OK ? res : B_BAD_DATA;

	BMemoryIO memIO(buf.get(), size);
	res = Unflatten(&memIO);

	return res;
}
Example #5
0
void
ActivityView::_LoadBackgroundInfo(bool watch)
{
	fCachedOutline = false;
	fCachedWorkspace = -1;
	BPath path;
	if (find_directory(B_DESKTOP_DIRECTORY, &path) == B_OK) {
		BNode desktopNode = BNode(path.Path());

		attr_info info;
		if (desktopNode.GetAttrInfo(kDesktopAttrName, &info) != B_OK)
			return;

		char* buffer = new char[info.size];
		if (desktopNode.ReadAttr(kDesktopAttrName, B_MESSAGE_TYPE, 0,
			buffer, (size_t)info.size) == info.size) {
				BMessage message;
				if (message.Unflatten(buffer) == B_OK)
					fBackgroundInfo = message;
		}
		delete[] buffer;

		if (watch) {
			node_ref nref;
			desktopNode.GetNodeRef(&nref);
			watch_node(&nref, B_WATCH_ATTR, this);
		}
	}
}
Example #6
0
/*! \brief Fetches the vector icon used by an application of this type for files of the
	given type.
	
	The type of the \c BMimeType object is not required to actually be a subtype of
	\c "application/"; that is the intended use however, and calling \c get_icon_for_type()
	on a non-application type will likely return \c B_ENTRY_NOT_FOUND.
	
	The icon data is allocated and returned in \a data.
	
	\param type The MIME type
	\param fileType Pointer to a pre-allocated string containing the MIME type whose
					custom icon you wish to fetch. If NULL, works just like get_icon().
	\param data Pointer in which the icon data is returned on success.
	\param size Pointer in which the size of the icon data is returned.
	\return
	- \c B_OK: Success
	- \c B_ENTRY_NOT_FOUND: No vector icon exists for the given type
	- "error code": Failure	

*/
status_t
get_icon_for_type(const char* type, const char* fileType, uint8** data,
				  size_t* size)
{
	if (!type || !data || !size)
		return B_BAD_VALUE;

	// open the node for the given type
	BNode node;
	ssize_t err = open_type(type, &node);
	if (err < B_OK)
		return (status_t)err;

	// construct our attribute name
	std::string iconAttrName;

	if (fileType)
		iconAttrName = kIconAttrPrefix + BPrivate::Storage::to_lower(fileType);
	else
		iconAttrName = kIconAttr;

	// get info about attribute for that name
	attr_info info;
	if (!err) 
		err = node.GetAttrInfo(iconAttrName.c_str(), &info);

	// validate attribute type
	if (!err)
		err = (info.type == B_VECTOR_ICON_TYPE) ? B_OK : B_BAD_VALUE;

	// allocate a buffer and read the attribute data into it
	if (!err) {
		uint8* buffer = new(std::nothrow) uint8[info.size];
		if (!buffer)
			err = B_NO_MEMORY;
		if (!err) {
			err = node.ReadAttr(iconAttrName.c_str(), B_VECTOR_ICON_TYPE,
								0, buffer, info.size);
		}

		if (err >= 0)
			err = (err == info.size) ? (ssize_t)B_OK : (ssize_t)B_FILE_ERROR;

		if (!err) {
			// success, set data pointer and size
			*data = buffer;
			*size = info.size;
		} else {
			delete[] buffer;
		}
	}

	return err;
}
Example #7
0
/*
 * this method is not currently being used, but it may be useful in the future...
 */
status_t
DefaultCatalog::ReadFromAttribute(entry_ref *appOrAddOnRef)
{
	BNode node;
	status_t res = node.SetTo(appOrAddOnRef);
	if (res != B_OK) {
		log_team(LOG_ERR,
			"couldn't find app or add-on (dev=%lu, dir=%Lu, name=%s)",
			appOrAddOnRef->device, appOrAddOnRef->directory,
			appOrAddOnRef->name);
		return B_ENTRY_NOT_FOUND;
	}

	log_team(LOG_DEBUG,
		"looking for embedded catalog-attribute in app/add-on"
		"(dev=%lu, dir=%Lu, name=%s)", appOrAddOnRef->device,
		appOrAddOnRef->directory, appOrAddOnRef->name);

	attr_info attrInfo;
	res = node.GetAttrInfo(BLocaleRoster::kEmbeddedCatAttr, &attrInfo);
	if (res != B_OK) {
		log_team(LOG_DEBUG, "no embedded catalog found");
		return B_NAME_NOT_FOUND;
	}
	if (attrInfo.type != B_MESSAGE_TYPE) {
		log_team(LOG_ERR, "attribute %s has incorrect type and is ignored!",
			BLocaleRoster::kEmbeddedCatAttr);
		return B_BAD_TYPE;
	}

	size_t size = attrInfo.size;
	auto_ptr<char> buf(new(std::nothrow) char [size]);
	if (buf.get() == NULL) {
		log_team(LOG_ERR, "couldn't allocate array of %d chars", size);
		return B_NO_MEMORY;
	}
	res = node.ReadAttr(BLocaleRoster::kEmbeddedCatAttr, B_MESSAGE_TYPE, 0,
		buf.get(), size);
	if (res < (ssize_t)size) {
		log_team(LOG_ERR, "unable to read embedded catalog from attribute");
		return res < B_OK ? res : B_BAD_DATA;
	}

	BMemoryIO memIO(buf.get(), size);
	res = Unflatten(&memIO);

	return res;
}
Example #8
0
/*	ReadSetting
*	this method can read attributes from a File, just give the name of the
*	attribute to the method (const char) and it returns a pointer to the content of the attribute.
*	It's importent that you know the type of the content because the method returns
* 	a void pointer and you have to make a typ caste to the return value to the expected
*	type of the attribute.
*	If there are errors the method throws exceptions
*/
void
*IOSettings::ReadSetting(const char* Setting)
{
	if(!SettingsFileExists())
		CreateSettingsFile();

	BNode objNode;
	char buffer[500];
	attr_info info;
	memset(buffer, 0, sizeof(buffer));

	//content pointer
	BString *strCont;
	int32 *int32Cont;
	int64 *int64Cont;
	double *dbCont;
	bool *blCont;
	
	objNode.SetTo(fSettingsFile.String());
	objNode.GetAttrInfo(Setting, &info);	
	switch(info.type)
	{
		case B_STRING_TYPE:
		{
			if(objNode.ReadAttr(Setting, info.type, 0, buffer, sizeof(buffer)) == B_ENTRY_NOT_FOUND)
				throw new IOSettingsException(new BString("an Attr. doesn't exsist by some folder (LavaProjectManager::_readPorject)"));
			
			strCont = new BString(buffer);
			return strCont;
		}
		break;
		case B_INT32_TYPE:
		{
			int32Cont = new int32();
			if(objNode.ReadAttr(Setting, info.type, 0, int32Cont, sizeof(int32Cont)) == B_ENTRY_NOT_FOUND)
				throw new IOSettingsException(new BString("an Attr. doesn't exsist by some folder (LavaProjectManager::_readPorject)"));
				
			return int32Cont;
		}
		break;
		case B_INT64_TYPE:
		{
			int64Cont = new int64();
			if(objNode.ReadAttr(Setting, info.type, 0, int64Cont, sizeof(int64Cont)) == B_ENTRY_NOT_FOUND)
				throw new IOSettingsException(new BString("an Attr. doesn't exsist by some folder (LavaProjectManager::_readPorject)"));
			
			return int64Cont;
		}
		break;
		case B_DOUBLE_TYPE:
		{
			dbCont = new double();
			if(objNode.ReadAttr(Setting, info.type, 0, dbCont, sizeof(dbCont)) == B_ENTRY_NOT_FOUND)
				throw new IOSettingsException(new BString("an Attr. doesn't exsist by some folder (LavaProjectManager::_readPorject)"));

			return dbCont;
		}
		break;
		case B_BOOL_TYPE:
		{
			blCont = new bool();
			if(objNode.ReadAttr(Setting, info.type, 0, blCont, sizeof(blCont)) == B_ENTRY_NOT_FOUND)
				throw new IOSettingsException(new BString("an Attr. doesn't exsist by some folder (LavaProjectManager::_readPorject)"));

			return blCont;
		}
		break;
		default:
			throw new IOSettingsException(new BString("not supported attribute type was read"));
		break;
	}
}
Example #9
0
QueryEntryListCollection::QueryEntryListCollection(Model* model,
	BHandler* target, PoseList* oldPoseList)
	:
	fQueryListRep(new QueryListRep(new BObjectList<BQuery>(5, true)))
{
	Rewind();
	attr_info info;
	BQuery query;

	BNode* modelNode = model->Node();
	if (modelNode == NULL) {
		fStatus = B_ERROR;
		return;
	}

	// read the actual query string
	fStatus = modelNode->GetAttrInfo(kAttrQueryString, &info);
	if (fStatus != B_OK)
		return;

	BString buffer;
	if (modelNode->ReadAttr(kAttrQueryString, B_STRING_TYPE, 0,
		buffer.LockBuffer((int32)info.size),
			(size_t)info.size) != info.size) {
		fStatus = B_ERROR;
		return;
	}

	buffer.UnlockBuffer();

	// read the extra options
	MoreOptionsStruct saveMoreOptions;
	if (ReadAttr(modelNode, kAttrQueryMoreOptions,
			kAttrQueryMoreOptionsForeign, B_RAW_TYPE, 0, &saveMoreOptions,
			sizeof(MoreOptionsStruct),
			&MoreOptionsStruct::EndianSwap) != kReadAttrFailed) {
		fQueryListRep->fShowResultsFromTrash = saveMoreOptions.searchTrash;
	}

	fStatus = query.SetPredicate(buffer.String());

	fQueryListRep->fOldPoseList = oldPoseList;
	fQueryListRep->fDynamicDateQuery = false;

	fQueryListRep->fRefreshEveryHour = false;
	fQueryListRep->fRefreshEveryMinute = false;

	if (modelNode->ReadAttr(kAttrDynamicDateQuery, B_BOOL_TYPE, 0,
			&fQueryListRep->fDynamicDateQuery,
			sizeof(bool)) != sizeof(bool)) {
		fQueryListRep->fDynamicDateQuery = false;
	}

	if (fQueryListRep->fDynamicDateQuery) {
		// only refresh every minute on debug builds
		fQueryListRep->fRefreshEveryMinute = buffer.IFindFirst("second") != -1
			|| buffer.IFindFirst("minute") != -1;
		fQueryListRep->fRefreshEveryHour = fQueryListRep->fRefreshEveryMinute
			|| buffer.IFindFirst("hour") != -1;

#if !DEBUG
		// don't refresh every minute unless we are running debug build
		fQueryListRep->fRefreshEveryMinute = false;
#endif
	}

	if (fStatus != B_OK)
		return;

	bool searchAllVolumes = true;
	status_t result = B_OK;

	// get volumes to perform query on
	if (modelNode->GetAttrInfo(kAttrQueryVolume, &info) == B_OK) {
		char* buffer = NULL;

		if ((buffer = (char*)malloc((size_t)info.size)) != NULL
			&& modelNode->ReadAttr(kAttrQueryVolume, B_MESSAGE_TYPE, 0,
				buffer, (size_t)info.size) == info.size) {
			BMessage message;
			if (message.Unflatten(buffer) == B_OK) {
				for (int32 index = 0; ;index++) {
					ASSERT(index < 100);
					BVolume volume;
						// match a volume with the info embedded in
						// the message
					result = MatchArchivedVolume(&volume, &message, index);
					if (result == B_OK) {
						// start the query on this volume
						result = FetchOneQuery(&query, target,
							fQueryListRep->fQueryList, &volume);
						if (result != B_OK)
							continue;

						searchAllVolumes = false;
					} else if (result != B_DEV_BAD_DRIVE_NUM) {
						// if B_DEV_BAD_DRIVE_NUM, the volume just isn't
						// mounted this time around, keep looking for more
						// if other error, bail
						break;
					}
				}
			}
		}

		free(buffer);
	}

	if (searchAllVolumes) {
		// no specific volumes embedded in query, search everything
		BVolumeRoster roster;
		BVolume volume;

		roster.Rewind();
		while (roster.GetNextVolume(&volume) == B_OK)
			if (volume.IsPersistent() && volume.KnowsQuery()) {
				result = FetchOneQuery(&query, target,
					fQueryListRep->fQueryList, &volume);
				if (result != B_OK)
					continue;
			}
	}

	fStatus = B_OK;

	return;
}
Example #10
0
status_t
AGMSBayesianSpamFilter::ProcessMailMessage (
	BPositionIO** io_message,
	BEntry* io_entry,
	BMessage* io_headers,
	BPath* io_folder,
	const char* io_uid)
{
	ssize_t		 amountRead;
	attr_info	 attributeInfo;
	const char	*classificationString;
	off_t		 dataSize;
	BPositionIO	*dataStreamPntr = *io_message;
	status_t	 errorCode = B_OK;
	int32        headerLength;
	BString      headerString;
	BString		 newSubjectString;
	BNode        nodeForOutputFile;
	bool		 nodeForOutputFileInitialised = false;
	const char	*oldSubjectStringPntr;
	char         percentageString [30];
	BMessage	 replyMessage;
	BMessage	 scriptingMessage;
	team_id		 serverTeam;
	float		 spamRatio;
	char		*stringBuffer = NULL;
	char         tempChar;
	status_t     tempErrorCode;
	const char  *tokenizeModeStringPntr;

	// Set up a BNode to the final output file so that we can write custom
	// attributes to it.  Non-custom attributes are stored separately in
	// io_headers.

	if (io_entry != NULL && B_OK == nodeForOutputFile.SetTo (io_entry))
		nodeForOutputFileInitialised = true;

	// Get a connection to the spam database server.  Launch if needed, should
	// only need it once, unless another e-mail thread shuts down the server
	// inbetween messages.  This code used to be in InitCheck, but apparently
	// that isn't called.

	printf("Checking for Spam Server.\n");
	if (fLaunchAttemptCount == 0 || !fMessengerToServer.IsValid ()) {
		if (fLaunchAttemptCount > 3)
			goto ErrorExit; // Don't try to start the server too many times.
		fLaunchAttemptCount++;

		// Make sure the server is running.
		if (!be_roster->IsRunning (kServerSignature)) {
			errorCode = be_roster->Launch (kServerSignature);
			if (errorCode != B_OK) {
				BPath path;
				entry_ref ref;
				directory_which places[] = {B_COMMON_BIN_DIRECTORY,B_BEOS_BIN_DIRECTORY};
				for (int32 i = 0; i < 2; i++) {
					find_directory(places[i],&path);
					path.Append("spamdbm");
					if (!BEntry(path.Path()).Exists())
						continue;
					get_ref_for_path(path.Path(),&ref);
					if ((errorCode =  be_roster->Launch (&ref)) == B_OK)
						break;
				}
				if (errorCode != B_OK)
					goto ErrorExit;
			}
		}

		// Set up the messenger to the database server.
		serverTeam = be_roster->TeamFor (kServerSignature);
		if (serverTeam < 0)
			goto ErrorExit;
		fMessengerToServer =
			BMessenger (kServerSignature, serverTeam, &errorCode);
		if (!fMessengerToServer.IsValid ())
			goto ErrorExit;

		// Check if the server is running in headers only mode.  If so, we only
		// need to download the header rather than the entire message.
		scriptingMessage.MakeEmpty ();
		scriptingMessage.what = B_GET_PROPERTY;
		scriptingMessage.AddSpecifier ("TokenizeMode");
		replyMessage.MakeEmpty ();
		if ((errorCode = fMessengerToServer.SendMessage (&scriptingMessage,
			&replyMessage)) != B_OK)
			goto ErrorExit;
		if ((errorCode = replyMessage.FindInt32 ("error", &tempErrorCode))
			!= B_OK)
			goto ErrorExit;
		if ((errorCode = tempErrorCode) != B_OK)
			goto ErrorExit;
		if ((errorCode = replyMessage.FindString ("result",
			&tokenizeModeStringPntr)) != B_OK)
			goto ErrorExit;
		fHeaderOnly = (tokenizeModeStringPntr != NULL
			&& strcmp (tokenizeModeStringPntr, "JustHeader") == 0);
	}

	// See if the message has already been classified.  Happens for messages
	// which are partially downloaded when you have auto-training on.  Could
	// untrain the partial part before training on the complete message, but we
	// don't know how big it was, so instead just ignore the message.

	if (nodeForOutputFileInitialised) {
		if (nodeForOutputFile.GetAttrInfo ("MAIL:classification",
			&attributeInfo) == B_OK)
			return B_OK;
	}

	// Copy the message to a string so that we can pass it to the spam database
	// (the even messier alternative is a temporary file).  Do it in a fashion
	// which allows NUL bytes in the string.  This method of course limits the
	// message size to a few hundred megabytes.  If we're using header mode,
	// only read the header rather than the full message.

	if (fHeaderOnly) {
		// Read just the header, it ends with an empty CRLF line.
		dataStreamPntr->Seek (0, SEEK_SET);
		while ((errorCode = dataStreamPntr->Read (&tempChar, 1)) == 1) {
			headerString.Append (tempChar, 1);
			headerLength = headerString.Length();
			if (headerLength >= 4 && strcmp (headerString.String() +
				headerLength - 4, "\r\n\r\n") == 0)
				break;
		}
		if (errorCode < 0)
			goto ErrorExit;

		dataSize = headerString.Length();
		stringBuffer = new char [dataSize + 1];
		memcpy (stringBuffer, headerString.String(), dataSize);
		stringBuffer[dataSize] = 0;
	} else {
		// Read the whole file.  The seek to the end may take a while since
		// that triggers downloading of the entire message (and caching in a
		// slave file - see the MessageIO class).
		dataSize = dataStreamPntr->Seek (0, SEEK_END);
		if (dataSize <= 0)
			goto ErrorExit;

		try {
			stringBuffer = new char [dataSize + 1];
		} catch (...) {
			errorCode = ENOMEM;
			goto ErrorExit;
		}

		dataStreamPntr->Seek (0, SEEK_SET);
		amountRead = dataStreamPntr->Read (stringBuffer, dataSize);
		if (amountRead != dataSize)
			goto ErrorExit;
		stringBuffer[dataSize] = 0; // Add an end of string NUL, just in case.
	}

	// Send off a scripting command to the database server, asking it to
	// evaluate the string for spaminess.  Note that it can return ENOMSG
	// when there are no words (a good indicator of spam which is pure HTML
	// if you are using plain text only tokenization), so we could use that
	// as a spam marker too.  Code copied for the reevaluate stuff below.

	scriptingMessage.MakeEmpty ();
	scriptingMessage.what = B_SET_PROPERTY;
	scriptingMessage.AddSpecifier ("EvaluateString");
	errorCode = scriptingMessage.AddData ("data", B_STRING_TYPE,
		stringBuffer, dataSize + 1, false /* fixed size */);
	if (errorCode != B_OK)
		goto ErrorExit;
	replyMessage.MakeEmpty ();
	errorCode = fMessengerToServer.SendMessage (&scriptingMessage,
		&replyMessage);
	if (errorCode != B_OK
		|| replyMessage.FindInt32 ("error", &errorCode) != B_OK)
		goto ErrorExit; // Unable to read the return code.
	if (errorCode == ENOMSG && fNoWordsMeansSpam)
		spamRatio = fSpamCutoffRatio; // Yes, no words and that means spam.
	else if (errorCode != B_OK
		|| replyMessage.FindFloat ("result", &spamRatio) != B_OK)
		goto ErrorExit; // Classification failed in one of many ways.

	// If we are auto-training, feed back the message to the server as a
	// training example (don't train if it is uncertain).  Also redo the
	// evaluation after training.

	if (fAutoTraining) {
		if (spamRatio >= fSpamCutoffRatio || spamRatio < fGenuineCutoffRatio) {
			scriptingMessage.MakeEmpty ();
			scriptingMessage.what = B_SET_PROPERTY;
			scriptingMessage.AddSpecifier ((spamRatio >= fSpamCutoffRatio)
				? "SpamString" : "GenuineString");
			errorCode = scriptingMessage.AddData ("data", B_STRING_TYPE,
				stringBuffer, dataSize + 1, false /* fixed size */);
			if (errorCode != B_OK)
				goto ErrorExit;
			replyMessage.MakeEmpty ();
			errorCode = fMessengerToServer.SendMessage (&scriptingMessage,
				&replyMessage);
			if (errorCode != B_OK
				|| replyMessage.FindInt32 ("error", &errorCode) != B_OK)
				goto ErrorExit; // Unable to read the return code.
			if (errorCode != B_OK)
				goto ErrorExit; // Failed to set a good example.
		}

		// Note the kind of example made so that the user doesn't reclassify
		// the message twice (the spam server looks for this attribute).

		classificationString =
			(spamRatio >= fSpamCutoffRatio)
			? "Spam"
			: ((spamRatio < fGenuineCutoffRatio) ? "Genuine" : "Uncertain");
		if (nodeForOutputFileInitialised)
			nodeForOutputFile.WriteAttr ("MAIL:classification", B_STRING_TYPE,
				0 /* offset */, classificationString,
				strlen (classificationString) + 1);

		// Now that the database has changed due to training, recompute the
		// spam ratio.  Hopefully it will have become more extreme in the
		// correct direction (not switched from being spam to being genuine).
		// Code copied from above.

		scriptingMessage.MakeEmpty ();
		scriptingMessage.what = B_SET_PROPERTY;
		scriptingMessage.AddSpecifier ("EvaluateString");
		errorCode = scriptingMessage.AddData ("data", B_STRING_TYPE,
			stringBuffer, dataSize + 1, false /* fixed size */);
		if (errorCode != B_OK)
			goto ErrorExit;
		replyMessage.MakeEmpty ();
		errorCode = fMessengerToServer.SendMessage (&scriptingMessage,
			&replyMessage);
		if (errorCode != B_OK
			|| replyMessage.FindInt32 ("error", &errorCode) != B_OK)
			goto ErrorExit; // Unable to read the return code.
		if (errorCode == ENOMSG && fNoWordsMeansSpam)
			spamRatio = fSpamCutoffRatio; // Yes, no words and that means spam.
		else if (errorCode != B_OK
			|| replyMessage.FindFloat ("result", &spamRatio) != B_OK)
			goto ErrorExit; // Classification failed in one of many ways.
	}

	// Store the spam ratio in an attribute called MAIL:ratio_spam,
	// attached to the eventual output file.

	if (nodeForOutputFileInitialised)
		nodeForOutputFile.WriteAttr ("MAIL:ratio_spam",
			B_FLOAT_TYPE, 0 /* offset */, &spamRatio, sizeof (spamRatio));

	// Also add it to the subject, if requested.

	if (fAddSpamToSubject
		&& spamRatio >= fSpamCutoffRatio
		&& io_headers->FindString ("Subject", &oldSubjectStringPntr) == B_OK) {
		newSubjectString.SetTo ("[Spam ");
		sprintf (percentageString, "%05.2f", spamRatio * 100.0);
		newSubjectString << percentageString << "%] ";
		newSubjectString << oldSubjectStringPntr;
		io_headers->ReplaceString ("Subject", newSubjectString);
	}

	// Beep using different sounds for spam and genuine, as Jeremy Friesner
	// nudged me to get around to implementing.  And add uncertain to that, as
	// "BiPolar" suggested.  If the user doesn't want to hear the sound, they
	// can turn it off in the system sound preferences.

	if (spamRatio >= fSpamCutoffRatio) {
		system_beep (kAGMSBayesBeepSpamName);
	} else if (spamRatio < fGenuineCutoffRatio) {
		system_beep (kAGMSBayesBeepGenuineName);
	} else {
		system_beep (kAGMSBayesBeepUncertainName);
	}

	return B_OK;

ErrorExit:
	fprintf (stderr, "Error exit from "
		"SpamFilter::ProcessMailMessage, code maybe %ld (%s).\n",
		errorCode, strerror (errorCode));
	delete [] stringBuffer;
	return B_OK; // Not MD_ERROR so the message doesn't get left on server.
}
Example #11
0
/*!
	Convert the plain text (UTF8) from inSource to plain or
	styled text in outDestination
*/
status_t
translate_from_text(BPositionIO* source, const char* encoding, bool forceEncoding,
                    BPositionIO* destination, uint32 outType)
{
    if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT)
        return B_BAD_VALUE;

    // find the length of the text
    off_t size = source->Seek(0, SEEK_END);
    if (size < 0)
        return (status_t)size;
    if (size > UINT32_MAX && outType == B_STYLED_TEXT_FORMAT)
        return B_NOT_SUPPORTED;

    status_t status = source->Seek(0, SEEK_SET);
    if (status < B_OK)
        return status;

    if (outType == B_STYLED_TEXT_FORMAT) {
        // output styled text headers
        status = output_headers(destination, (uint32)size);
        if (status != B_OK)
            return status;
    }

    class MallocBuffer {
    public:
        MallocBuffer() : fBuffer(NULL), fSize(0) {}
        ~MallocBuffer() {
            free(fBuffer);
        }

        void* Buffer() {
            return fBuffer;
        }
        size_t Size() const {
            return fSize;
        }

        status_t
        Allocate(size_t size)
        {
            fBuffer = malloc(size);
            if (fBuffer != NULL) {
                fSize = size;
                return B_OK;
            }
            return B_NO_MEMORY;
        }

    private:
        void*	fBuffer;
        size_t	fSize;
    } encodingBuffer;
    BMallocIO encodingIO;
    uint32 encodingID = 0;
    // defaults to UTF-8 or no encoding

    BNode* node = dynamic_cast<BNode*>(source);
    if (node != NULL) {
        // determine encoding, if available
        const BCharacterSet* characterSet = NULL;
        bool hasAttribute = false;
        if (encoding != NULL && !forceEncoding) {
            BString name;
            if (node->ReadAttrString("be:encoding", &name) == B_OK) {
                encoding = name.String();
                hasAttribute = true;
            } else {
                int32 value;
                ssize_t bytesRead = node->ReadAttr("be:encoding", B_INT32_TYPE, 0,
                                                   &value, sizeof(value));
                if (bytesRead == (ssize_t)sizeof(value)) {
                    hasAttribute = true;
                    if (value != 65535)
                        characterSet = BCharacterSetRoster::GetCharacterSetByConversionID(value);
                }
            }
        } else {
            hasAttribute = true;
            // we don't write the encoding in this case
        }
        if (characterSet == NULL && encoding != NULL)
            characterSet = BCharacterSetRoster::FindCharacterSetByName(encoding);

        if (characterSet != NULL) {
            encodingID = characterSet->GetConversionID();
            encodingBuffer.Allocate(READ_BUFFER_SIZE * 4);
        }

        if (!hasAttribute && encoding != NULL) {
            // add encoding attribute, so that someone opening the file can
            // retrieve it for persistance
            node->WriteAttr("be:encoding", B_STRING_TYPE, 0, encoding,
                            strlen(encoding));
        }
    }

    off_t outputSize = 0;
    ssize_t bytesRead;
    int32 state = 0;

    // output the actual text part of the data
    do {
        uint8 buffer[READ_BUFFER_SIZE];
        bytesRead = source->Read(buffer, READ_BUFFER_SIZE);
        if (bytesRead < B_OK)
            return bytesRead;
        if (bytesRead == 0)
            break;

        if (encodingBuffer.Size() == 0) {
            // default, no encoding
            ssize_t bytesWritten = destination->Write(buffer, bytesRead);
            if (bytesWritten != bytesRead) {
                if (bytesWritten < B_OK)
                    return bytesWritten;

                return B_ERROR;
            }

            outputSize += bytesRead;
        } else {
            // decode text file to UTF-8
            char* pos = (char*)buffer;
            int32 encodingLength = encodingIO.BufferLength();
            int32 bytesLeft = bytesRead;
            int32 bytes;
            do {
                encodingLength = READ_BUFFER_SIZE * 4;
                bytes = bytesLeft;

                status = convert_to_utf8(encodingID, pos, &bytes,
                                         (char*)encodingBuffer.Buffer(), &encodingLength, &state);
                if (status < B_OK)
                    return status;

                ssize_t bytesWritten = destination->Write(encodingBuffer.Buffer(),
                                       encodingLength);
                if (bytesWritten < encodingLength) {
                    if (bytesWritten < B_OK)
                        return bytesWritten;

                    return B_ERROR;
                }

                pos += bytes;
                bytesLeft -= bytes;
                outputSize += encodingLength;
            } while (encodingLength > 0 && bytesLeft > 0);
        }
    } while (bytesRead > 0);

    if (outType != B_STYLED_TEXT_FORMAT)
        return B_OK;

    if (encodingBuffer.Size() != 0 && size != outputSize) {
        if (outputSize > UINT32_MAX)
            return B_NOT_SUPPORTED;

        // we need to update the header as the decoded text size has changed
        status = destination->Seek(0, SEEK_SET);
        if (status == B_OK)
            status = output_headers(destination, (uint32)outputSize);
        if (status == B_OK)
            status = destination->Seek(0, SEEK_END);

        if (status < B_OK)
            return status;
    }

    // Read file attributes if outputting styled data
    // and source is a BNode object

    if (node == NULL)
        return B_OK;

    // Try to read styles - we only propagate an error if the actual on-disk
    // data is likely to be okay

    const char *kAttrName = "styles";
    attr_info info;
    if (node->GetAttrInfo(kAttrName, &info) != B_OK)
        return B_OK;

    if (info.type != B_RAW_TYPE || info.size < 160) {
        // styles seem to be broken, but since we got the text,
        // we don't propagate the error
        return B_OK;
    }

    uint8* flatRunArray = new (std::nothrow) uint8[info.size];
    if (flatRunArray == NULL)
        return B_NO_MEMORY;

    bytesRead = node->ReadAttr(kAttrName, B_RAW_TYPE, 0, flatRunArray, info.size);
    if (bytesRead != info.size)
        return B_OK;

    output_styles(destination, size, flatRunArray, info.size);

    delete[] flatRunArray;
    return B_OK;
}
status_t
CreateAppMetaMimeThread::DoMimeUpdate(const entry_ref* ref, bool* _entryIsDir)
{
    if (ref == NULL)
        return B_BAD_VALUE;

    BNode typeNode;

    BFile file;
    status_t status = file.SetTo(ref, B_READ_ONLY);
    if (status < B_OK)
        return status;

    bool isDir = file.IsDirectory();
    if (_entryIsDir != NULL)
        *_entryIsDir = isDir;

    if (isDir)
        return B_OK;

    BAppFileInfo appInfo(&file);
    status = appInfo.InitCheck();
    if (status < B_OK)
        return status;

    // Read the app sig (which consequently keeps us from updating
    // non-applications, since we get an error if the file has no
    // app sig)
    BString signature;
    status = file.ReadAttrString("BEOS:APP_SIG", &signature);
    if (status < B_OK)
        return B_BAD_TYPE;

    // Init our various objects

    BMimeType mime;
    status = mime.SetTo(signature.String());
    if (status < B_OK)
        return status;

    InstallNotificationDeferrer _(fDatabase, signature.String());

    if (!mime.IsInstalled())
        mime.Install();

    BString path = "/";
    path.Append(signature);
    path.ToLower();
    // Signatures and MIME types are case insensitive, but we want to
    // preserve the case wherever possible
    path.Prepend(get_database_directory().c_str());

    status = typeNode.SetTo(path.String());
    if (status < B_OK)
        return status;

    // Preferred App
    attr_info info;
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kPreferredAppAttr, &info) != B_OK))
        status = mime.SetPreferredApp(signature.String());

    // Short Description (name of the application)
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kShortDescriptionAttr, &info) != B_OK))
        status = mime.SetShortDescription(ref->name);

    // App Hint
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kAppHintAttr, &info) != B_OK))
        status = mime.SetAppHint(ref);

    // Vector Icon
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kIconAttr, &info) != B_OK)) {
        uint8* data = NULL;
        size_t size = 0;
        if (appInfo.GetIcon(&data, &size) == B_OK) {
            status = mime.SetIcon(data, size);
            free(data);
        }
    }
    // Mini Icon
    BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kMiniIconAttr, &info) != B_OK)) {
        if (appInfo.GetIcon(&miniIcon, B_MINI_ICON) == B_OK)
            status = mime.SetIcon(&miniIcon, B_MINI_ICON);
    }
    // Large Icon
    BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kLargeIconAttr, &info) != B_OK)) {
        if (appInfo.GetIcon(&largeIcon, B_LARGE_ICON) == B_OK)
            status = mime.SetIcon(&largeIcon, B_LARGE_ICON);
    }

    // Supported Types
    bool setSupportedTypes = false;
    BMessage supportedTypes;
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kSupportedTypesAttr, &info) != B_OK)) {
        if (appInfo.GetSupportedTypes(&supportedTypes) == B_OK)
            setSupportedTypes = true;
    }

    // defer notifications for supported types
    const char* type;
    for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
        fDatabase->DeferInstallNotification(type);

    // set supported types
    if (setSupportedTypes)
        status = mime.SetSupportedTypes(&supportedTypes);

    // Icons for supported types
    for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++) {
        // vector icon
        uint8* data = NULL;
        size_t size = 0;
        if (status == B_OK && appInfo.GetIconForType(type, &data, &size) == B_OK) {
            status = mime.SetIconForType(type, data, size);
            free(data);
        }
        // mini icon
        if (status == B_OK && appInfo.GetIconForType(type, &miniIcon, B_MINI_ICON) == B_OK)
            status = mime.SetIconForType(type, &miniIcon, B_MINI_ICON);
        // large icon
        if (status == B_OK && appInfo.GetIconForType(type, &largeIcon, B_LARGE_ICON) == B_OK)
            status = mime.SetIconForType(type, &largeIcon, B_LARGE_ICON);
    }

    // undefer notifications for supported types
    for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
        fDatabase->UndeferInstallNotification(type);

    return status;
}