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

📄 pgparmor.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 3 页
字号:
				  context->inlen);

	/* Apply padding so that we can overshoot */
	if (context->inlen < sizeof (context->input))
		context->input[context->inlen] = 0;
	
	/* Refill the output buffer from the input buffer */
	context->outlen = armorLine (context->input, context->inlen,
				     context->output);

	context->output [context->outlen++] = '\n';
	context->outptr = context->output;
	context->inlen = 0;
}

static PGPError
Flush (PGPPipeline *myself)
{
	ArmorContext *context;
	PGPError	error;
	size_t retlen;

	pgpAssert (myself);
	pgpAssert (myself->magic == ARMORMAGIC);

	context = (ArmorContext *)myself->priv;
	pgpAssert (context);
	pgpAssert (context->tail);

	/* Try to flush anything that we have buffered. */
	while (context->outlen) {
		retlen = context->tail->write (context->tail,
					       (PGPByte *)context->outptr,
					       context->outlen,
					       &error);
		context->outlen -= retlen;
		context->outptr += retlen;

		if (!context->outlen)
			context->lineno++;

		if (error)
			return error;
	}

	return kPGPError_NoErr;
}

/*
 * First, try to flush out the output buffer.  Once that is empty,
 * refill the output buffer from the input buffer, append a newline,
 * and set the input buffer to 0 input.  Then try to write that out,
 * too.
 */
static PGPError
DoFlush (PGPPipeline *myself)
{
	ArmorContext *context = (ArmorContext *)myself->priv;
	PGPError	error = kPGPError_NoErr;

	/*
	 * Try to flush anything that we have buffered.  I know that
	 * the first time Flush is called, outlen WILL be zero!
	 */
	error = Flush (myself);
	if (error)
		return error;

	/* Next, try to output anything in the header fifo */
	error = armorFlushHeader (context);
	if (error)
		return error;


	/* Finally, process the input buffer and flush it out again */
	if (context->inlen) {
		armorProcessLine (context);
		error = DoFlush (myself);
	}

	return error;
}

/*
 * Write a single line.
 */
static size_t
armorWriteBytes (PGPPipeline *myself, PGPByte const *buf, size_t size,
		 PGPError *error)
{
	ArmorContext *context = (ArmorContext *)myself->priv;
	size_t size0 = size;
	unsigned t;

	/*
	 * Try to flush anything that we have buffered.  I know that
	 * the first time Flush is called, outlen WILL be zero!
	 */
	*error = Flush (myself);
	if (*error)
		return 0;

	/* try to fill up the input buffer */
	t = pgpMin ((sizeof (context->input) - context->inlen), size);
	memcpy (context->input + context->inlen, buf, t);
	buf += t;
	size -= t;
	context->inlen += t;

	if( context->inlen ) {
		armorWriteClassify (context, context->input);
		
		/*
		 * check if we need a new file.  This is called if we
		 * exceed armorlines, or when we do have multiparts and we do
		 * not have a current part.
		 */
		if (context->armorlines && (context->lineno >=
					    context->armorlines ||
					    !context->thispart)) {

			/*
			 * Set maxparts to -1 if this _is_ multipart armor
			 * using one-pass processing.
			 */
			if (context->version > PGPVERSION_3 &&
			    !context->maxparts && !context->sizevalid)
				context->maxparts = -1;

			*error = armorNewFile (myself);
			if (*error)
				return size0-size;
		}
	}

	/* If we've filled a line, then flush it out */
	if (context->inlen == sizeof (context->input)) {
		if (!context->didheader)
			armorMakeHeader (context);
		*error = DoFlush (myself);
		if (*error)
			return size0-size;
	}

	return size0-size;
}

/*
 * Minimally perform a DoFlush(), but try to flush the fifo, too!
 *
 * If context->version > PGPVERSION_3 then we only start writing
 * things out context->armorlines == 0 or when we have a full block
 * worth of data (48 * (context->armorlines - context->lineno)).  If
 * context->sizevalid == 2, we have an EOF and should flush the rest
 * of the fifo regardless.
 */
static PGPError
armorFlushFifo (PGPPipeline *myself)
{
	ArmorContext *context = (ArmorContext *)myself->priv;
	PGPByte const *ptr;
	PGPSize len;
	size_t retlen;
	PGPError	error;

	ptr = pgpFifoPeek (context->fd, context->fifo, &len);
	while (len) {
		if (context->version > PGPVERSION_3 &&
		    context->sizevalid < 2 &&
		    context->armorlines &&
		    pgpFifoSize (context->fd, context->fifo) < 48 *
		    (context->lineno == context->armorlines ? 
		     context->armorlines :
		     (context->armorlines - context->lineno)))
			return kPGPError_NoErr;

		retlen = armorWriteBytes (myself, ptr, len, &error);
		pgpFifoSeek (context->fd, context->fifo, retlen);
		if (error)
			return error;

		ptr = pgpFifoPeek (context->fd, context->fifo, &len);
	}
	return kPGPError_NoErr;
}

/*
 * This is the function that processes a clearsigned message.  It uses
 * context->state to tell it what it is doing:
 *	0) at the beginning -- check it
 *	1) middle of line, pass it through
 * 2) end of line with \r -- check next character for \n */
static size_t
armorDoClearsign (PGPPipeline *myself, PGPByte const *buf, size_t size,
		  PGPError *error)
{
	ArmorContext *context = (ArmorContext *)myself->priv;
	size_t written, size0 = size;
	PGPByte const *ptr;
	static PGPByte const from[] = "From ";
	int i, t, flag;

	
	while (size) {
		if (context->state == 2) {
			context->state = 0;
			if (*buf == '\n') {
				ptr = buf+1;
				goto do_write;
			}
		}
			
		/* 
		 * Here, we check the beginning of the line.  We use the
		 * flag to denote what we've found/buffered:
		 *	0) no match
		 *	1) full match
		 *	2) partial match (and we buffered data)
		 */
		if (!context->state) {
			flag = 0;
			if (!context->linebuf) {
				/* nothing is buffered */
				if (*buf == '-')
					flag = 1;
			}
			if (!flag) {
				t = pgpMin (5, size - context->linebuf);
				for (i = 0; i < t; i++)
					if (buf[i] != from[context->linebuf +
							   i]) {
						pgpFifoWrite
							(context->fd,
							 context->header,
							 context->input,
							 context->linebuf);
						context->linebuf = 0;
						break;
					}
				if (i == t) {
					/* We matched the whole input buffer */
					if (i + context->linebuf == 5)
						flag = 1;
					else {
						memcpy (context->input +
							context->linebuf, buf,
							t);
						context->linebuf += t;
						size -= t;
						buf += t;
						flag = 2;
					}
				}
			}
			if (flag == 1) {
				pgpFifoWrite (context->fd, context->header,
					      (PGPByte const *)"- ", 2);
				if (context->linebuf) {
					pgpFifoWrite (context->fd,
						      context->header,
						      context->input,
						      context->linebuf);
					context->linebuf = 0;
				}
			}

			if (flag != 2)
				context->state = 1;
		}

		*error = armorFlushHeader (context);
		if (*error)
			return size0 - size;

		for (ptr = buf; ptr < buf+size; ptr++) {
			if (*ptr == '\r' || *ptr == '\n') {
				context->state = (*ptr++ == '\r') ?
					2 : 0;
				break;
			}
		}

do_write:
		written = context->tail->write (context->tail, buf,
						ptr-buf, error);
		buf += written;
		size -= written;
		if (*error)
			return size0 - size;

	}
	
	return size0 - size;
}

/*
 * This function creates a pgp-mime multipart/signed (clearsigned) message.
 * We are now assuming that caller is responsible for giving us a good,
 * MIME formatted body part.  So we just pass it through.
 */
static size_t
armorDoMimesign (PGPPipeline *myself, PGPByte const *buf, size_t size,
		 PGPError *error)
{
	ArmorContext *context = (ArmorContext *)myself->priv;
	size_t written, size0 = size;

	while (size) {
		written = context->tail->write (context->tail, buf, size, error);
		buf += written;
		size -= written;
		if (*error)
			return size0 - size;
	}
	
	return size0 - size;
}

static size_t
Write (PGPPipeline *myself, PGPByte const *buf, size_t size, PGPError *error)
{
	ArmorContext *context;
	size_t retval, written = 0;

	pgpAssert (myself);
	pgpAssert (myself->magic == ARMORMAGIC);
	pgpAssert (error);

	context = (ArmorContext *)myself->priv;
	pgpAssert (context);
	pgpAssert (context->tail);

	if (context->outlen) {
		*error = DoFlush (myself);
		if (*error)
			return 0;
	}

	if (context->clearsign) {
		if (context->pgpmime)
			return armorDoMimesign (myself, buf, size, error);
		else
			return armorDoClearsign (myself, buf, size, error);
	}

	if (!context->sizevalid || context->version > PGPVERSION_3) {
		written = pgpFifoWrite (context->fd, context->fifo, buf, size);

		if (context->version <= PGPVERSION_3)
			return written;
	}

	*error = armorFlushFifo (myself);
	if (*error || context->version > PGPVERSION_3)
		return written;

	/* Try to write all the data we were given */
	do {
		retval = armorWriteBytes (myself, buf, size, error);
		written += retval;
		buf += retval;
		size -= retval;
		if (*error)
			return written;
	} while (size);

	return written;
}

static PGPError
Annotate (PGPPipeline *myself, PGPPipeline *origin, int type,
	  PGPByte const *string, size_t size)
{
	ArmorContext *context;
	PGPError	error = kPGPError_NoErr;

	pgpAssert (myself);
	pgpAssert (myself->magic == ARMORMAGIC);

	context = (ArmorContext *)myself->priv;
	pgpAssert (context);

	switch( type ) {
	case PGPANN_PGPMIME_HEADER_SIZE:
		pgpAssert( size == sizeof(PGPSize) );
		*(PGPSize *)string = context->mimebodyoff;
		break;
	case PGPANN_PGPMIME_HEADER_LINES:
		pgpAssert( size == sizeof(PGPUInt32) );
		*(PGPUInt32 *)string = context->mimeheaderlines;
		break;
	case PGPANN_PGPMIME_SEPARATOR:
		if (context->pgpmime == PGPMIMEENC) {
			strncpy((char *)string, MIMEENCSEP,
					pgpMin(size, strlen(MIMEENCSEP)+1));
		} else {
			strncpy((char *)string, context->mimesigsep,
					pgpMin(size, NSEPCHARS+1));
		}
		break;
	default:
		if (context->tail)
			error = context->tail->annotate (context->tail, origin, type,
						 string, size);
		break;
	}
	if (!error)
		PGP_SCOPE_DEPTH_UPDATE(context->scope_depth, type);
	pgpAssert(context->scope_depth != -1);
	return error;
}

static PGPError
SizeAdvise (PGPPipeline *myself, unsigned long bytes)
{
	ArmorContext *context;
	PGPError	error = kPGPError_NoErr;
	unsigned long total;

	pgpAssert (myself);
	pgpAssert (myself->magic == ARMORMAGIC);

	context = (ArmorContext *)myself->priv;
	pgpAssert (context);
	pgpAssert (context->tail);

	/* Only handle bytes until EOF */
	if (context->scope_depth)
		return kPGPError_NoErr;

	/* Then compute maxparts */
	if (!context->sizevalid) {
		if (context->armorlines) {
			total = bytes + pgpFifoSize (context->fd,
						     context->fifo);

			if (context->version > PGPVERSION_3 && 
			    context->thispart) {
				total += 48 * context->armorlines *
					(context->thispart - 1);
				total += 48 * context->lineno;
			}

			/* 48 bytes / line */
			context->maxparts = total / (context->armorlines * 48);
			if (context->maxparts)
				context->maxparts++;

⌨️ 快捷键说明

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