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

📄 pgpreadann.c

📁 PGP—Pretty Good Privacy
💻 C
📖 第 1 页 / 共 2 页
字号:
		} else {
			pgpAssert(PGP_IS_END_SCOPE (type));

			if (context->stack[context->sp - 1] != type - 1)
				context->ui->message (context->ui_arg,
						      kPGPError_UnbalancedScope,
						      PGPMSG_UNBALANCED_SCOPE,
						      0);
			else {
				context->stack[--context->sp] = 0;
				context->sepsig[context->sp] = 0;
			}

		}
		/*
		 * For clearsigned messages, preserve type.  See comments
		 * re PGPANN_CLEARSIG_BEGIN/END below.  Otherwise go back
		 * to type of next annotation on the stack.
		 */
		if (!(type==PGPANN_ARMOR_BEGIN &&
					      context->type==PGP_LITERAL_TEXT))
			if (context->sp)
				context->type = context->stack[context->sp-1];
	}

	if (context->ui->annotate) {
		error = (PGPError)context->ui->annotate (context->ui_arg, origin,
					       type, string, size);
		if (error)
			return error;
	}

	switch (type) {
	case PGPANN_COMMIT:
		do {
			i = context->ui->doCommit 
				(context->ui_arg,
				 context->stack[context->sp - 1]);

			/* Allow commit function to abort us */
			if (i < 0) {
				return i;
			}

			if (i != PGPANN_PARSER_PASSTHROUGH &&
			    i != PGPANN_PARSER_EATIT &&
			    i != PGPANN_PARSER_PROCESS &&
			    i != PGPANN_PARSER_RECURSE) {
				msgarg1.type = PGP_UI_ARG_INT;
				msgarg1.val.i = i;
				context->ui->message (context->ui_arg,
						      kPGPError_InvalidCommit,
						      PGPMSG_COMMIT_INVALID,
						      1,
						      &msgarg1);
				continue;
			}

			if (i < PGPANN_PARSER_PROCESS) {
				error = origin->annotate (origin, myself, i,
				                          0, 0);
				if (error) 
					context->ui->message
						(context->ui_arg, error,
						 PGPMSG_ANNOTATE_ERROR, 0);
			} else if (context->stack[context->sp-1] ==
			                          PGPANN_CIPHER_BEGIN) {
				error = (PGPError)eskdecrypt(myself, origin, i);
				if (error) {
					context->ui->message
						(context->ui_arg, error,
						 PGPMSG_ESK_NODECRYPT, 0);
					break;
				}
			} else if (context->stack[context->sp-1] ==
			                          PGPANN_SIGNED_BEGIN) {
				if (context->sepsig[context->sp-1]) {
					error = (PGPError)sepsighash(context);
					if (error) {
						context->ui->message
						   (context->ui_arg, error,
						    PGPMSG_SEPSIG_NOVERIFY, 0);
						break;
					}
				} else {
					error = (PGPError)sighash(myself, origin, i);
					if (error) {
						context->ui->message
						   (context->ui_arg, error,
						    PGPMSG_SIG_NOVERIFY, 0);
						break;
					}
				}
			} else {
				error = origin->annotate (origin, myself, i,
				                          0, 0);
				if (error)
					context->ui->message
						(context->ui_arg, error,
						 PGPMSG_ANNOTATE_ERROR, 0);
			}
			/* The idea of looping until the error goes away does not seem
			 * practical.  If it failed once, it will almost always fail
			 * again.
			 */
			if (error)
				return error;
		} while (error);
		break;
	case PGPANN_PKCIPHER_ESK:
	case PGPANN_SKCIPHER_ESK:
		i = pgpEskAdd( cdkContext, &context->esklist, type, string, size);
		if (i != 0) {
			context->ui->message (context->ui_arg, i,
					      PGPMSG_ESK_ADD_ERROR, 0);
		}
		break;

	case PGPANN_SIGNED_SIG:
	case PGPANN_SIGNED_SIG2:
		/* Add signature for */
		i = pgpSigAdd ( cdkContext, &context->siglist[context->sp-1], type,
			       string, size);
		if (i != 0) {
			context->ui->message (context->ui_arg, i,
					      PGPMSG_SIG_ADD_ERROR, 0);
		}
		break;

	case PGPANN_SIGNED_SEP:
		/* This signature context is for a separate signature */
		context->sepsig[context->sp-1] = 1;
		break;
	case PGPANN_SIGNED_END:
		error = (PGPError)sigtry(myself, origin);
		break;
	case PGPANN_HASH_VALUE:
		error = (PGPError)sigverify(myself, string, size);
		break;
	case PGPANN_LITERAL_TYPE:
		if (size)
			context->type = string[0];
		break;
	case PGPANN_LITERAL_NAME:
		if (size) {
			if (context->name)
				pgpContextMemFree( cdkContext, context->name);
			context->name = (char *)pgpContextMemAlloc( cdkContext,
				size+1, kPGPMemoryMgrFlags_Clear);
			if (context->name)
			{
				memcpy (context->name, string, size);
				context->name[size] = 0;
			}
			else
				error = kPGPError_OutOfMemory;
		}
		break;
	/*
	 * The actual sequence is: PGPANN_CLEARSIG_BEGIN, PGPANN_CLEARSIG_END,
	 * PGPANN_ARMOR_BEGIN, and then we do a Write when we want our type
	 * to be PGP_LITERAL_TEXT.  So it takes some careful work here and
	 * above.
	 */
	case PGPANN_CLEARSIG_BEGIN:
	case PGPANN_CLEARSIG_END:
		/* Clearsigned messages are always text! */
		context->type = PGP_LITERAL_TEXT;
		break;
	default:
		; /* Do nothing */
	}

	/* At end of scope, shut down output */
	if (!error && PGP_IS_END_SCOPE (type) && context-> sp < context->file_sp)
	{
		/* We are now closing tail during the annotation callback */
		if (context->tail)
			error = context->tail->sizeAdvise (context->tail, 0);
		if (!error) {
			if (context->name) {
				pgpContextMemFree( cdkContext, context->name);
				context->name = NULL;
			}
			context->type = -1;
			context->newoutput = 1;
		}
	}

	return error;
}

static PGPError
Flush (PGPPipeline *myself)
{
	ReadAnnContext *context;

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

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

	if (!context->tail)
		return( kPGPError_NoErr );

	return context->tail->flush (context->tail);
}

static PGPError
SizeAdvise (PGPPipeline *myself, unsigned long bytes)
{
	ReadAnnContext *context;
	PGPError	error = kPGPError_NoErr;
	PGPContextRef	cdkContext;
	
	pgpAssertAddrValid( myself, PGPPipeline );
	cdkContext	= myself->cdkContext;

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

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

	if (!bytes && context->tail) {
		error = context->tail->sizeAdvise (context->tail, bytes);
		if (!error) {
			if (context->name) {
				pgpContextMemFree( cdkContext, context->name);
				context->name = NULL;
			}
			context->type = -1;
			context->newoutput = 1;
		}
	}
	return error;
}

static PGPError
Teardown (PGPPipeline *myself)
{
	ReadAnnContext *context;
	PGPContextRef	cdkContext;
	
	pgpAssertAddrValid( myself, PGPPipeline );
	cdkContext	= myself->cdkContext;

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

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

	pgpEskFreeList (context->esklist);
	context->esklist = 0;
	if (context->name)
		pgpContextMemFree( cdkContext, context->name);
	context->name = 0;
	if (context->tail)
		context->tail->teardown (context->tail);

	pgpClearMemory( context,  sizeof (*context));
	pgpContextMemFree( cdkContext, context);
	
	return kPGPError_NoErr;
}

PGPPipeline **
pgpAnnotationReaderCreate (
	PGPContextRef cdkContext,
	PGPPipeline **head,
			   PGPEnv const *env,
			   PGPUICb const *ui, void *arg)
{
	PGPPipeline *mod;
	ReadAnnContext *context;

	if (!head || !env)
		return NULL;

	*head = 0;

	context = (ReadAnnContext *)pgpContextMemAlloc( cdkContext,
		sizeof (*context), kPGPMemoryMgrFlags_Clear);
	if (!context)
		return NULL;
	mod = &context->pipe;

	mod->magic = READANNOTATIONMAGIC;
	mod->write = Write;
	mod->flush = Flush;
	mod->sizeAdvise = SizeAdvise;
	mod->annotate = Annotate;
	mod->teardown = Teardown;
	mod->name = "Simple Annotation Reader";
	mod->priv = context;
	mod->cdkContext	= cdkContext;

	context->ui = ui;
	context->ui_arg = arg;
	context->env = env;
	context->newoutput = 1;
	context->type = -1;

	*head = mod;
	return &context->tail;
}

⌨️ 快捷键说明

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