Пример #1
1
status_t
POP3Protocol::SyncMessages()
{
	bool leaveOnServer;
	if (fSettings.FindBool("leave_mail_on_server", &leaveOnServer) != B_OK)
		leaveOnServer = true;

	// create directory if not exist
	create_directory(fDestinationDir, 0777);

	printf("POP3Protocol::SyncMessages()\n");
	_ReadManifest();

	SetTotalItems(2);
	ReportProgress(0, 1, "Connect to server...");
	status_t error = Connect();
	if (error < B_OK) {
		ResetProgress();
		return error;
	}

	ReportProgress(0, 1, MDR_DIALECT_CHOICE("Getting UniqueIDs...",
		"固有のIDを取得中..."));
	error = _UniqueIDs();
	if (error < B_OK) {
		ResetProgress();
		return error;
	}

	BStringList toDownload;
	fManifest.NotHere(fUniqueIDs, &toDownload);

	int32 numMessages = toDownload.CountItems();
	if (numMessages == 0) {
		CheckForDeletedMessages();
		ResetProgress();
		return B_OK;
	}

	ResetProgress();
	SetTotalItems(toDownload.CountItems());

	printf("POP3: Messages to download: %i\n", (int)toDownload.CountItems());
	for (int32 i = 0; i < toDownload.CountItems(); i++) {
		const char* uid = toDownload.ItemAt(i);
		int32 toRetrieve = fUniqueIDs.IndexOf(uid);

		if (toRetrieve < 0) {
			// should not happen!
			error = B_NAME_NOT_FOUND;
			printf("POP3: uid %s index %i not found in fUniqueIDs!\n", uid,
				(int)toRetrieve);
			continue;
		}

		BPath path(fDestinationDir);
		BString fileName = "Downloading file... uid: ";
		fileName += uid;
		fileName.ReplaceAll("/", "_SLASH_");
		path.Append(fileName);
		BEntry entry(path.Path());
		BFile file(&entry, B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
		error = file.InitCheck();
		if (error != B_OK) {
			printf("POP3: Can't create file %s\n ", path.Path());
			break;
		}
		BMailMessageIO mailIO(this, &file, toRetrieve);

		entry_ref ref;
		entry.GetRef(&ref);

		// the ref becomes invalid after renaming the file thus we already
		// write the status here
		MarkMessageAsRead(ref, B_UNREAD);

		int32 size = MessageSize(toRetrieve);
		if (fFetchBodyLimit < 0 || size <= fFetchBodyLimit) {
			error = mailIO.Seek(0, SEEK_END);
			if (error < 0) {
				printf("POP3: Failed to download body %s\n ", uid);
				break;
			}
			NotifyHeaderFetched(ref, &file);
			NotifyBodyFetched(ref, &file);

			if (!leaveOnServer)
				Delete(toRetrieve);
		} else {
			int32 dummy;
			error = mailIO.ReadAt(0, &dummy, 1);
			if (error < 0) {
				printf("POP3: Failed to download header %s\n ", uid);
				break;
			}
			NotifyHeaderFetched(ref, &file);
		}
		ReportProgress(0, 1);

		if (file.WriteAttr("MAIL:unique_id", B_STRING_TYPE, 0, uid,
			strlen(uid)) < 0) {
			error = B_ERROR;
		}

		file.WriteAttr("MAIL:size", B_INT32_TYPE, 0, &size, sizeof(int32));

		// save manifest in case we get disturbed
		fManifest += uid;
		_WriteManifest();
	}

	ResetProgress();

	CheckForDeletedMessages();
	Disconnect();
	return error;
}
Пример #2
0
status_t
POP3Protocol::DeleteMessage(const entry_ref& ref)
{
	status_t error = Connect();
	if (error < B_OK)
		return error;

	error = _UniqueIDs();
	if (error < B_OK) {
		Disconnect();
		return error;
	}

	char uidString[256];
	BNode node(&ref);
	if (node.ReadAttr("MAIL:unique_id", B_STRING_TYPE, 0, uidString, 256) < 0) {
		Disconnect();
		return B_ERROR;
	}

	#if DEBUG
	printf("DeleteMessage: ID is %d\n", (int)fUniqueIDs.IndexOf(uidString));
		// What should we use for int32 instead of %d?
	#endif
	Delete(fUniqueIDs.IndexOf(uidString));

	Disconnect();
	return B_OK;
}
Пример #3
0
status_t
POP3Protocol::FetchBody(const entry_ref& ref)
{
	ResetProgress("Fetch body");
	SetTotalItems(1);

	status_t error = Connect();
	if (error < B_OK)
		return error;

	error = _UniqueIDs();
	if (error < B_OK) {
		Disconnect();
		return error;
	}

	BFile file(&ref, B_READ_WRITE);
	status_t status = file.InitCheck();
	if (status != B_OK) {
		Disconnect();
		return status;
	}

	char uidString[256];
	BNode node(&ref);
	if (node.ReadAttr("MAIL:unique_id", B_STRING_TYPE, 0, uidString, 256) < 0) {
		Disconnect();
		return B_ERROR;
	}

	int32 toRetrieve = fUniqueIDs.IndexOf(uidString);
	if (toRetrieve < 0) {
		Disconnect();
		return B_NAME_NOT_FOUND;
	}

	bool leaveOnServer;
	if (fSettings.FindBool("leave_mail_on_server", &leaveOnServer) != B_OK)
		leaveOnServer = true;

	// TODO: get rid of this BMailMessageIO!
	BMailMessageIO io(this, &file, toRetrieve);
	// read body
	status = io.Seek(0, SEEK_END);
	if (status < 0) {
		Disconnect();
		return status;
	}

	NotifyBodyFetched(ref, &file);

	if (!leaveOnServer)
		Delete(toRetrieve);

	ReportProgress(0, 1);
	ResetProgress();

	Disconnect();
	return B_OK;
}