📄 pgpreadann.c
字号:
} 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 + -