Пример #1
0
	void
ParseMIMEType(
	const char*			szText,
	emsMIMEtype**	ppMimeType
)
{
	*ppMimeType	= NULL;
	
	*ppMimeType = parse_make_mime_type(szText);

	if ( *ppMimeType )
	{
		// parse_mime_ct doesn't fill in mime_version
		(*ppMimeType)->mime_version = strdup( "1.0");
	}
}
Пример #2
0
/*  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)
			{
				if (pCT)
				{
					*mimePtr = parse_make_mime_type(pCT);
				}
				else
				{
					*mimePtr = make_mime_type("text", "plain", "1.0");
				}
			}

			safefree(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 */
				safefree(pCTE);
			}

			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);
		}

		safefree(pHeader)
		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);
}