예제 #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
파일: POP3.cpp 프로젝트: AmirAbrams/haiku
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(1, 0, B_TRANSLATE("Connect to server" B_UTF8_ELLIPSIS));

	status_t error = Connect();
	if (error != B_OK) {
		printf("POP3 could not connect: %s\n", strerror(error));
		ResetProgress();
		return error;
	}

	ReportProgress(1, 0, B_TRANSLATE("Getting UniqueIDs" B_UTF8_ELLIPSIS));

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

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

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

	ResetProgress();
	SetTotalItems(toDownload.CountStrings());
	SetTotalItemsSize(fTotalSize);

	printf("POP3: Messages to download: %i\n", (int)toDownload.CountStrings());
	for (int32 i = 0; i < toDownload.CountStrings(); i++) {
		const char* uid = toDownload.StringAt(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);
		BMessage attributes;

		entry_ref ref;
		entry.GetRef(&ref);

		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;
			}
			ProcessMessageFetched(ref, file, attributes);

			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;
			}
			ProcessHeaderFetched(ref, file, attributes);
		}
		ReportProgress(1, 0);

		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));
		write_read_attr(file, B_UNREAD);

		// save manifest in case we get disturbed
		fManifest.Add(uid);
		_WriteManifest();
	}

	ResetProgress();

	CheckForDeletedMessages();
	Disconnect();
	return error;
}