⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file1847.cpp

📁 著名的加密软件的应用于电子邮件中
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	else
		return (FALSE); // Could not create buffer

	return (ret != RFC1847_FAIL);
}

/* ------------------------------------------------------------------------ */

/*  DoCreateOnePart (static)
 *
 *  Private function used to pipe a given file through the 1847 creator as
 *  either part 1 or part 2. All De-mime stuff is also done here.
 */
static int DoCreateOnePart(emsMIMEtypeP InPartMimePtr,
					 emsMIMEtypeP OutMimePtr,
					 TrEncType InPartCTE,
					 FILE *fIn,
					 FILE *fOut,
					 int nPart,
					 long nPreLen,
					 long nTotalInLen,
					 createStatePtr pState,
					 emsProgress progress)
{
	BufTypePtr pInBuf = makesize_buf(kBufferSize);

	if (!pInBuf)
		return (FILE1847_FAIL); // Could not create buffer -- error

	int nStatus = FILE1847_OK;

	// Do InPartMimePtr (Content-Type) header
	if ((nStatus == FILE1847_OK) && (InPartMimePtr))
	{
		char *pCT = string_mime_type(InPartMimePtr);
		
		if (pCT)
		{
			if (!DoCreateStringOutput(pCT, nPart, OutMimePtr, pState, fOut))
				nStatus = FILE1847_FAIL;
			else
				if (!DoCreateStringOutput("\r\n", nPart, OutMimePtr, pState, fOut))
					nStatus = FILE1847_FAIL;
		}
		else
			nStatus = FILE1847_FAIL;

		safefree(pCT);
	}

	// Do InPartCTE (Content-Transfer-Encoding) header
	if ((nStatus == FILE1847_OK) && (InPartCTE != CTE_NONE))
	{
		char *pCTE = rfc822_make_cte(InPartCTE);
		
		if (pCTE)
		{
			if (!DoCreateStringOutput(pCTE, nPart, OutMimePtr, pState, fOut))
				nStatus = FILE1847_FAIL;
			else
				if (!DoCreateStringOutput("\r\n", nPart, OutMimePtr, pState, fOut))
					nStatus = FILE1847_FAIL;
		}
		else
			nStatus = FILE1847_FAIL;

		safefree(pCTE);
	}

	// Do blank line -- only if we put out some header already
	if ((nStatus == FILE1847_OK) && ((InPartMimePtr) || (InPartCTE != CTE_NONE)))
	{
		if (!DoCreateStringOutput("\r\n", nPart, OutMimePtr, pState, fOut))
			nStatus = FILE1847_FAIL;
	}

	char *preEncBuffer = NULL;
	unsigned int preEncBufLen;

	Enc64Ptr e64state = NULL; // Used by Encode64()
	EncQPPtr eQPstate = NULL; // Used by EucodeQP()

	if (nStatus == FILE1847_OK)
	{
		switch (InPartCTE)
		{
			// BASE64
			case CTE_Base64:
			{
				// BASE64 expands about 1/3
				preEncBufLen = ((kBufferSize * 6) / 10);
				preEncBuffer = (char *) malloc(preEncBufLen);

				if (!preEncBuffer)
					nStatus = FILE1847_FAIL; // Could not create buffer

				e64state = (Enc64Ptr) malloc(sizeof(Enc64)); // Used by Encode64()
				e64state->partialCount = e64state->bytesOnLine = 0;
			}
			break;

			// QUOTED-PRINTABLE
			case CTE_QP:
			{
				// QP expands max of 3 times
				preEncBufLen = (kBufferSize / 4);
				preEncBuffer = (char *) malloc(preEncBufLen);

				if (!preEncBuffer)
					nStatus = FILE1847_FAIL; // Could not create buffer

				eQPstate = (EncQPPtr) malloc(sizeof(EncQP)); // Used by Encode64()
				eQPstate->nCurLineLen = 0;
				eQPstate->cLastChar = '\0';
			}
			break;

			// Otherwise, no encoding
			default:
			{
				preEncBufLen = 0;
			}
			break;
		}
	}

	size_t nReadLen = 0;
	int nPercentComplete = 0;

	// Do pInPartFilename
	while ((nStatus == FILE1847_OK) && (!feof(fIn)) && (!ferror(fIn)))
	{
		emptybuf_buf(pInBuf);

		switch (InPartCTE)
		{
			case CTE_Base64:
			{
				nReadLen = fread(preEncBuffer, sizeof(char), preEncBufLen, fIn);
				nReadLen = Encode64(preEncBuffer, nReadLen, getbuf_buf(pInBuf), e64state);
			}
			break;

			case CTE_QP:
			{
				nReadLen = fread(preEncBuffer, sizeof(char), preEncBufLen, fIn);
				nReadLen = EncodeQP(preEncBuffer, nReadLen, getbuf_buf(pInBuf), eQPstate);
			}
			break;

			default: /* 7bit, 8bit, binary, none */
			{
				nReadLen = fread(getbuf_buf(pInBuf), sizeof(char), bufsize_buf(pInBuf), fIn);
			}
			break;
		}

		if (nReadLen > 0)
		{
			setlen_buf(pInBuf, nReadLen);

			if (!DoCreatePartsOutput(OutMimePtr,
					((nPart == 1) ? pInBuf : NULL), /* Part 1 */
					((nPart == 2) ? pInBuf : NULL), /* Part 2 */
					pState,
					fOut))
				nStatus = FILE1847_FAIL;
		}

		if ((nStatus == FILE1847_OK) && (progress))
		{
			// Update the progress and check for abort
			nPercentComplete = (int) (((((double)ftell(fIn) + nPreLen))/nTotalInLen) * 100.0);
			if (progress(nPercentComplete) ? 1 : 0)
				nStatus = FILE1847_ABORT;
		}
	}

	if (nStatus == FILE1847_OK)
	{
		// Finish part -- if needed
		switch (InPartCTE)
		{
			case CTE_Base64:
			{
				nReadLen = Encode64(NULL, 0, getbuf_buf(pInBuf), e64state);
			}
			break;

			case CTE_QP:
			{
				nReadLen = EncodeQP(NULL, 0, getbuf_buf(pInBuf), eQPstate);
			}
			break;

			default: /* 7bit, 8bit, binary, none */
			{
				nReadLen = 0;
			}
			break;
		}

		if (nReadLen > 0)
		{
			setlen_buf(pInBuf, nReadLen);

			if (!DoCreatePartsOutput(OutMimePtr,
					((nPart == 1) ? pInBuf : NULL), /* Part 1 */
					((nPart == 2) ? pInBuf : NULL), /* Part 2 */
					pState,
					fOut))
				nStatus = FILE1847_FAIL;
		}
	}

	safefree(e64state);
	safefree(eQPstate);
	safefree(preEncBuffer);
	delete_buf(pInBuf);

	return (nStatus);
}

/* ------------------------------------------------------------------------ */

/*  DoParsePart (static)
 *
 *  Private function used to pipe the output of 1847 parsing into a file.
 */
static int DoParsePart(BufTypePtr pInBuf,
				 FILE *fOut,
				 emsMIMEtypeP *mimePtr,
				 int bDeMime,
				 PartParseStatePtr pState)
{
	if (!pInBuf) // Input buf NULL indicates 'cleanup'
	{
		if (!pState->bFoundHeader)
			return (FALSE);
		else
			return (TRUE);
	}

	if (!pState->bFoundHeader)
	{
		resetpos_buf(pState->pSearchBuf);

		if (pState->nPrevEndMatch > 0)
		{
			/* Check for completion of span */

			// If doesn't continue match, returns zero
			// otherwise returns number of chars of pSearchBuf that have been matched
			unsigned int nNewMatched = completecount_buf(pInBuf, pState->pSearchBuf, pState->nPrevEndMatch);

			if (nNewMatched == buflen_buf(pState->pSearchBuf)) /* complete match made */
			{
				pState->bFoundHeader = TRUE;
				pState->nPrevEndMatch = 0;
				bufncat_buf(pState->pBuf, pInBuf, (buflen_buf(pState->pSearchBuf) - (pState->nPrevEndMatch)));
			}
			else if (nNewMatched != 0) /* Continued to match, but not completed yet -- the input buffer is smaller than the pSearchBuf */
			{
				bufncat_buf(pState->pBuf, pInBuf, poslen_buf(pInBuf));
				pState->nPrevEndMatch = nNewMatched;
				return (TRUE);
			}
			else /* No match continuation */
			{
				pState->nPrevEndMatch = 0;
			}
		}

		resetpos_buf(pState->pSearchBuf);

		// Still not found -- no span
		if (!pState->bFoundHeader)
		{
			// Find match of pSearchBuf, either complete or end-spanning
			// return number of chars to skip before match
			unsigned int nSkip = skipcount_buf(pInBuf, pState->pSearchBuf);
			unsigned int nRemain = poslen_buf(pInBuf) - nSkip;

			if (nRemain == 0) // Not found
			{
				bufncat_buf(pState->pBuf, pInBuf, poslen_buf(pInBuf));
				return (TRUE);
			}
			else
			if (nRemain > buflen_buf(pState->pSearchBuf)) /* Found 'complete' */
			{
				pState->bFoundHeader = TRUE;
				bufncat_buf(pState->pBuf, pInBuf, (nSkip + buflen_buf(pState->pSearchBuf)) );
			}
			else // Partial possible
			{
				pState->nPrevEndMatch = nRemain;
				bufncat_buf(pState->pBuf, pInBuf, poslen_buf(pInBuf));
				return (TRUE);
			}
		}

		// ---------- Now we know it is found ----------

		unsigned int nLen = buflen_buf(pState->pBuf);
		char *pHeader = (char *) malloc(nLen + 1);
		strncpy(pHeader, getbuf_buf(pState->pBuf), nLen);

		char *pCT = rfc822_extract_header(pHeader, "Content-Type:");

		if (mimePtr)
			*mimePtr = parse_make_mime_type(pCT);

		if (bDeMime)
		{
			char *pCTE = rfc822_extract_cte(pHeader);
			if (pCTE)
				pState->cte = rfc822_parse_cte(pCTE);
			else
				pState->cte = CTE_NONE; /* No CTE header, so no encoding */

			switch (pState->cte)
			{
				// BASE64
				case CTE_Base64:
				{
					// BASE64 expands about 1/3
					unsigned int preEncBufLen = ((kBufferSize * 10) / 6);
					pState->preEncBuffer = (char *) malloc(preEncBufLen);

					pState->d64state = (Dec64Ptr) malloc(sizeof(Dec64)); // Used by Decode64()
					pState->d64state->decoderState = 0;
					pState->d64state->invalCount = 0;
					pState->d64state->padCount = 0;
					pState->d64state->partial = 0;
					pState->d64state->wasCR = FALSE;
				}
				break;

				// QUOTED-PRINTABLE
				case CTE_QP:
				{
					// QP expands max of 3 times
					unsigned int preEncBufLen = (kBufferSize * 4);
					pState->preEncBuffer = (char *) malloc(preEncBufLen);

					pState->dQPstate = (DecQPPtr) malloc(sizeof(EncQP));
					pState->dQPstate->CurState = qpNormal;
					pState->dQPstate->cLastChar = 0;
				}
				break;

				// Otherwise, no encoding
				default:
				break;
			}
		}
		else
		{
			fwrite(getbuf_buf(pState->pBuf), sizeof(char), nLen, fOut);
		}

		free_buf(pState->pBuf);
	}

	// ---------- Now we know it is found and header is init'd ----------

	long errorcnt;

	switch (pState->cte)
	{
		case CTE_Base64:
		{
			unsigned int nReadLen = Decode64(getpos_buf(pInBuf), poslen_buf(pInBuf), pState->preEncBuffer, pState->d64state, &errorcnt);
			fwrite(pState->preEncBuffer, sizeof(char), nReadLen, fOut);
		}
		break;

		case CTE_QP:
		{
			unsigned int nReadLen = DecodeQP(getpos_buf(pInBuf), poslen_buf(pInBuf), pState->preEncBuffer, pState->dQPstate, &errorcnt);
			fwrite(pState->preEncBuffer, sizeof(char), nReadLen, fOut);
		}
		break;

		default: /* 7bit, 8bit, binary, none */
		{
			fwrite(getpos_buf(pInBuf), sizeof(char), poslen_buf(pInBuf), fOut);
		}
		break;
	}

	return (TRUE);
}

/* ------------------------------------------------------------------------ */

/*  create_PartParseState (static)
 *
 *  Private function used initialize the parse state.
 */
static PartParseStatePtr create_PartParseState()
{
	PartParseStatePtr p = (PartParseStatePtr) malloc(sizeof(PartParseState));

	if (p)
	{
		p->bFoundHeader = FALSE;
		p->pBuf = make_buf();
		p->pSearchBuf = make_buf();
		strcpy_buf(p->pSearchBuf, "\r\n\r\n");
		p->cte = CTE_NONE;
		p->nPrevEndMatch = 0;
		p->preEncBuffer = NULL;
		p->d64state = NULL;
		p->dQPstate = NULL;
	}

	return (p);
}

/* ------------------------------------------------------------------------ */

/*  delete_PartParseState (static)
 *
 *  Private function used to delete the parse state.
 */
static void delete_PartParseState(PartParseStatePtr p)
{
	if (p)
	{
		delete_buf(p->pBuf);
		delete_buf(p->pSearchBuf);
		safefree(p->preEncBuffer);
		safefree(p->d64state);
		safefree(p->dQPstate);
		
		safefree(p);
	}
}

/* ------------------------------------------------------------------------ */

/*  DoBufOutput (static)
 *
 *  Private function used to output a buffer.
 */
static void DoBufOutput(FILE *fOut, BufTypePtr pBuf)
{
	fwrite(getpos_buf(pBuf), sizeof(char), poslen_buf(pBuf), fOut);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -