Beispiel #1
0
status_t
write_read_attr(BNode& node, read_flags flag)
{
	if (node.WriteAttr(B_MAIL_ATTR_READ, B_INT32_TYPE, 0, &flag, sizeof(int32))
		< 0)
		return B_ERROR;

#if R5_COMPATIBLE
	// manage the status string only if it currently has a "read" status
	BString currentStatus;
	if (node.ReadAttrString(B_MAIL_ATTR_STATUS, &currentStatus) == B_OK) {
		if (currentStatus.ICompare("New") != 0
			&& currentStatus.ICompare("Read") != 0
			&& currentStatus.ICompare("Seen") != 0)
			return B_OK;
	}

	const char* statusString = (flag == B_READ) ? "Read"
		: (flag  == B_SEEN) ? "Seen" : "New";
	if (node.WriteAttr(B_MAIL_ATTR_STATUS, B_STRING_TYPE, 0, statusString,
		strlen(statusString)) < 0)
		return B_ERROR;
#endif
	return B_OK;
}
void
BepdfApplication::UpdateAttr(BNode &node, const char *name, type_code type, off_t offset, void *buffer, size_t length) {
	char dummy[10];
	if (B_ENTRY_NOT_FOUND == node.ReadAttr(name, type, offset, (char*)dummy, sizeof(dummy))) {
		node.WriteAttr(name, type, offset, buffer, length);
	}
}
/* 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 */
Beispiel #4
0
status_t
IMAPFolder::_WriteUInt32(BNode& node, const char* attribute, uint32 value) const
{
	ssize_t bytesWritten = node.WriteAttr(attribute, B_UINT32_TYPE, 0,
		&value, sizeof(uint32));
	if (bytesWritten == (ssize_t)sizeof(uint32))
		return B_OK;

	return bytesWritten < 0 ? bytesWritten : B_IO_ERROR;
}
Beispiel #5
0
status_t
IMAPStorage::_WriteUniqueID(BNode& node, int32 uid)
{
    BString uidString;
    uidString << uid;
    ssize_t written = node.WriteAttr("MAIL:unique_id", B_STRING_TYPE, 0,
                                     uidString.String(), uidString.Length());
    if (written < 0)
        return written;
    return B_OK;
}
Beispiel #6
0
/*	WriteSetting
*	this method writes a setting to the settings file (boolean)
*/
void IOSettings::WriteSetting(const char* Setting, bool SettCont)
{
	if(!SettingsFileExists())
		CreateSettingsFile();

	BNode objNode;
	objNode.SetTo(fSettingsFile.String());
	
	if(objNode.WriteAttr(Setting, B_BOOL_TYPE, 0, (void*)&SettCont, sizeof(SettCont)) == B_FILE_ERROR)
		throw new IOSettingsException(new BString("can't write attr. to settings file (IOSettings::WriteSetting(const char* Setting, bool SettCont))"));

}
Beispiel #7
0
/*	WriteSetting
*	this method writes a setting to the settings file (strings(BString))
*/
void IOSettings::WriteSetting(const char* Setting, BString SettCont)
{
	if(!SettingsFileExists())
		CreateSettingsFile();

	BNode objNode;
	objNode.SetTo(fSettingsFile.String());
	
	if(objNode.WriteAttr(Setting, B_STRING_TYPE, 0, SettCont.String(), SettCont.Length()) == B_FILE_ERROR)
		throw new IOSettingsException(new BString("can't write attr. to settings file (IOSettings::WriteSetting(const char* Setting, BString SettCont))"));

}
Beispiel #8
0
status_t
IMAPStorage::_WriteFlags(int32 flags, BNode& node)
{
    if ((flags & kSeen) != 0)
        write_read_attr(node, B_READ);
    else
        write_read_attr(node, B_UNREAD);

    ssize_t writen = node.WriteAttr("MAIL:server_flags", B_INT32_TYPE, 0,
                                    &flags, sizeof(int32));
    if (writen != sizeof(int32))
        return writen;

    return B_OK;
}
Beispiel #9
0
// Add or Remove OpenTracker's Restore attribute
void SFileWorker::ModifyRestoreAttribute(const SFileList *fileList, bool add)
{
	SFile *file;
	BNode node;
	
	for(int32 i=0; i<fileList->CountItems();i++)
	{
		file=(SFile*)fileList->ItemAt(i);
		if(!file)
			continue;

		if(node.SetTo(file->Ref())!=B_OK)
			continue;
		
		if(add)
		{
			node.WriteAttr("_trk/original_path",B_STRING_TYPE,0,
				file->PathDesc(),strlen(file->PathDesc())+1);
		}
		else
			node.RemoveAttr("_trk/original_path");
	}
}
Beispiel #10
0
/*
 * this method is not currently being used, but it may be useful in the
 * future...
 */
status_t
DefaultCatalog::WriteToAttribute(entry_ref *appOrAddOnRef)
{
	BNode node;
	status_t res = node.SetTo(appOrAddOnRef);
	if (res != B_OK)
		return res;

	BMallocIO mallocIO;
	mallocIO.SetBlockSize(max(fCatMap.Size() * 20, 256L));
		// set a largish block-size in order to avoid reallocs
	res = Flatten(&mallocIO);

	if (res == B_OK) {
		ssize_t wsz;
		wsz = node.WriteAttr(BLocaleRoster::kEmbeddedCatAttr, B_MESSAGE_TYPE, 0,
			mallocIO.Buffer(), mallocIO.BufferLength());
		if (wsz < B_OK)
			res = wsz;
		else if (wsz != (ssize_t)mallocIO.BufferLength())
			res = B_ERROR;
	}
	return res;
}
/*
iterate over add-on-folders and collect information about each
catalog-add-ons (types of catalogs) into fCatalogAddOnInfos.
*/
status_t
LocaleRosterData::_InitializeCatalogAddOns()
{
	BAutolock lock(fLock);
	if (!lock.IsLocked())
		return B_ERROR;

	// add info about embedded default catalog:
	CatalogAddOnInfo* defaultCatalogAddOnInfo
		= new(std::nothrow) CatalogAddOnInfo("Default", "",
			DefaultCatalog::kDefaultCatalogAddOnPriority);
	if (!defaultCatalogAddOnInfo)
		return B_NO_MEMORY;

	defaultCatalogAddOnInfo->fInstantiateFunc = DefaultCatalog::Instantiate;
	defaultCatalogAddOnInfo->fCreateFunc = DefaultCatalog::Create;
	fCatalogAddOnInfos.AddItem((void*)defaultCatalogAddOnInfo);

	directory_which folders[] = {
		B_USER_ADDONS_DIRECTORY,
		B_COMMON_ADDONS_DIRECTORY,
		B_SYSTEM_ADDONS_DIRECTORY,
	};
	BPath addOnPath;
	BDirectory addOnFolder;
	char buf[4096];
	status_t err;
	for (uint32 f = 0; f < sizeof(folders) / sizeof(directory_which); ++f) {
		find_directory(folders[f], &addOnPath);
		BString addOnFolderName(addOnPath.Path());
		addOnFolderName << "/locale/catalogs";

		system_info info;
		if (get_system_info(&info) == B_OK
				&& (info.abi & B_HAIKU_ABI_MAJOR)
				!= (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR)) {
			switch (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR) {
				case B_HAIKU_ABI_GCC_2:
					addOnFolderName << "/gcc2";
					break;
				case B_HAIKU_ABI_GCC_4:
					addOnFolderName << "/gcc4";
					break;
			}
		}


		err = addOnFolder.SetTo(addOnFolderName.String());
		if (err != B_OK)
			continue;

		// scan through all the folder's entries for catalog add-ons:
		int32 count;
		int8 priority;
		entry_ref eref;
		BNode node;
		BEntry entry;
		dirent* dent;
		while ((count = addOnFolder.GetNextDirents((dirent*)buf, 4096)) > 0) {
			dent = (dirent*)buf;
			while (count-- > 0) {
				if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")
						&& strcmp(dent->d_name, "gcc2")
						&& strcmp(dent->d_name, "gcc4")) {
					// we have found (what should be) a catalog-add-on:
					eref.device = dent->d_pdev;
					eref.directory = dent->d_pino;
					eref.set_name(dent->d_name);
					entry.SetTo(&eref, true);
						// traverse through any links to get to the real thang!
					node.SetTo(&entry);
					priority = -1;
					if (node.ReadAttr(kPriorityAttr, B_INT8_TYPE, 0,
						&priority, sizeof(int8)) <= 0) {
						// add-on has no priority-attribute yet, so we load it
						// to fetch the priority from the corresponding
						// symbol...
						BString fullAddOnPath(addOnFolderName);
						fullAddOnPath << "/" << dent->d_name;
						image_id image = load_add_on(fullAddOnPath.String());
						if (image >= B_OK) {
							uint8* prioPtr;
							if (get_image_symbol(image, "gCatalogAddOnPriority",
								B_SYMBOL_TYPE_DATA,
								(void**)&prioPtr) == B_OK) {
								priority = *prioPtr;
								node.WriteAttr(kPriorityAttr, B_INT8_TYPE, 0,
									&priority, sizeof(int8));
							}
							unload_add_on(image);
						}
					}

					if (priority >= 0) {
						// add-ons with priority < 0 will be ignored
						CatalogAddOnInfo* addOnInfo
							= new(std::nothrow) CatalogAddOnInfo(dent->d_name,
								addOnFolderName, priority);
						if (addOnInfo)
							fCatalogAddOnInfos.AddItem((void*)addOnInfo);
					}
				}
				// Bump the dirent-pointer by length of the dirent just handled:
				dent = (dirent*)((char*)dent + dent->d_reclen);
			}
		}
	}
	fCatalogAddOnInfos.SortItems(CompareInfos);

	return B_OK;
}
/*
iterate over add-on-folders and collect information about each
catalog-add-ons (types of catalogs) into fCatalogAddOnInfos.
*/
status_t
LocaleRosterData::_InitializeCatalogAddOns()
{
	BAutolock lock(fLock);
	if (!lock.IsLocked())
		return B_ERROR;

	// add info about embedded default catalog:
	CatalogAddOnInfo* defaultCatalogAddOnInfo
		= new(std::nothrow) CatalogAddOnInfo("Default", "",
			DefaultCatalog::kDefaultCatalogAddOnPriority);
	if (!defaultCatalogAddOnInfo)
		return B_NO_MEMORY;

	defaultCatalogAddOnInfo->fInstantiateFunc = DefaultCatalog::Instantiate;
	defaultCatalogAddOnInfo->fCreateFunc = DefaultCatalog::Create;
	fCatalogAddOnInfos.AddItem((void*)defaultCatalogAddOnInfo);

	BStringList folders;
	BPathFinder::FindPaths(B_FIND_PATH_ADD_ONS_DIRECTORY, "locale/catalogs/",
		B_FIND_PATH_EXISTING_ONLY, folders);

	BPath addOnPath;
	BDirectory addOnFolder;
	char buf[4096];
	status_t err;
	for (int32 f = 0; f < folders.CountStrings(); f++) {
		BString addOnFolderName = folders.StringAt(f);
		err = addOnFolder.SetTo(addOnFolderName.String());
		if (err != B_OK)
			continue;

		// scan through all the folder's entries for catalog add-ons:
		int32 count;
		int8 priority;
		entry_ref eref;
		BNode node;
		BEntry entry;
		dirent* dent;
		while ((count = addOnFolder.GetNextDirents((dirent*)buf, sizeof(buf)))
				> 0) {
			dent = (dirent*)buf;
			while (count-- > 0) {
				if (strcmp(dent->d_name, ".") != 0
						&& strcmp(dent->d_name, "..") != 0
						&& strcmp(dent->d_name, "x86") != 0
						&& strcmp(dent->d_name, "x86_gcc2") != 0) {
					// we have found (what should be) a catalog-add-on:
					eref.device = dent->d_pdev;
					eref.directory = dent->d_pino;
					eref.set_name(dent->d_name);
					entry.SetTo(&eref, true);
						// traverse through any links to get to the real thang!
					node.SetTo(&entry);
					priority = -1;
					if (node.ReadAttr(kPriorityAttr, B_INT8_TYPE, 0,
						&priority, sizeof(int8)) <= 0) {
						// add-on has no priority-attribute yet, so we load it
						// to fetch the priority from the corresponding
						// symbol...
						BString fullAddOnPath(addOnFolderName);
						fullAddOnPath << "/" << dent->d_name;
						image_id image = load_add_on(fullAddOnPath.String());
						if (image >= B_OK) {
							uint8* prioPtr;
							if (get_image_symbol(image, "gCatalogAddOnPriority",
								B_SYMBOL_TYPE_DATA,
								(void**)&prioPtr) == B_OK) {
								priority = *prioPtr;
								node.WriteAttr(kPriorityAttr, B_INT8_TYPE, 0,
									&priority, sizeof(int8));
							}
							unload_add_on(image);
						}
					}

					if (priority >= 0) {
						// add-ons with priority < 0 will be ignored
						CatalogAddOnInfo* addOnInfo
							= new(std::nothrow) CatalogAddOnInfo(dent->d_name,
								addOnFolderName, priority);
						if (addOnInfo)
							fCatalogAddOnInfos.AddItem((void*)addOnInfo);
					}
				}
				// Bump the dirent-pointer by length of the dirent just handled:
				dent = (dirent*)((char*)dent + dent->d_reclen);
			}
		}
	}
	fCatalogAddOnInfos.SortItems(CompareInfos);

	return B_OK;
}
Beispiel #13
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.
}
Beispiel #14
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;
}