📄 pgpexit.c
字号:
}
/*
* This recursively calls itself until it has eaten enough stack,
* then wipes it.
* ASSUMPTIONS: it assumes that the stack is contiguous and grows downwards.
* (This is reasonably portable in practice,
* even though counterexamples exist.)
* If these are violated, who knows what will happen!
*/
static void
exitWipe(int code)
{
char buf[1024];
if (stack0 && (char *)stack0 - buf < 16384)
exitWipe(code); /* Recursive call to fill stack */
exitWipe1(code, buf);
}
#endif /* !MSDOS */
void exitVersion(void)
{
PrimaryOutputString("\
U.S. Patent numbers 4,200,770, 4,218,582, 4,405,829, and 4,424,414\n\
licensed exlusively by Public Key Partners.\n\
U.S. Patent number 5,214,703 licensed by Ascom Tech A.G.\n\
\n\
Copyright (C) 1997 Pretty Good Privacy, Inc. All rights reserved.\n\
PGP and Pretty Good Privacy are trademarks of Pretty Good Privacy,\n\
Inc. All other trademarks are property of their respective holders.\n\
Export of this software may be restricted by the U.S. Government.\n\
\n\
Version: %s%s%s%s\n",
VERSION_OS,
VERSION_MAJOR,
VERSION_MINOR,
VERSION_SUB);
exitCleanup(0);
}
void
exitCleanup(int code)
{
FILE *rs;
char const *fn;
/* close everything */
mainCloseKeyrings (1, newversion);
if (env0) {
pgpRandPoolKeystroke (code); /* Maybe it's an interrupt? */
fn = pgpenvGetString (env0, PGPENV_RANDSEED, NULL, NULL);
rs = fopen (fn, "wb");
if (rs) {
pgpRandSeedWrite (rs, NULL, NULL);
fclose (rs);
}
pgpenvDestroy (env0);
}
fclose(stdin);
fclose(stdout);
fclose(stderr);
exitWipe(code);
}
#ifdef MSDOS
/*
* DOS Error codes from 0x13 to 0x27 are reported as critical errors,
* But they are mapped to 0..0x14 before being passed in di. Some
* fancy extensions (like networks) can create more.
* Actually, 0x
*/
static char const * const doserrs[] = {
"Write protect error$",
"Unknown unit$",
"Drive not ready$",
"Unknown command$",
"Data error (bad CRC)$",
"Bad request structure length$",
"Write protect error$",
"Seek error$",
"Unknown media type$",
"Sector not found$",
"Printer out of paper$",
"Write fault$",
"Read fault$",
"General failure"
"Sharing violation$",
"Lock violation$",
"Invalid disk change$",
"FCD unavailable$",
"System resource exhausted$",
"Code page mismatch$",
"Out of input$",
"Insufficient disk space$",
"Unknown error$" /* Catch-all */
};
static char const * const readwrite[] = {
"Reading", "Writing"
};
static char const * const area[] = {
"DOS area", "file allocation table", "disk directory", "file area"
};
#ifndef __BORLANDC__
/*
* Microsoft Visual C somehow distinguishes between "const void __far *"
* (which works) and "void const __far *" and "void __far const *"
* (which don't). I have no idea why. If you move the const after the void,
* trying to pass a "char const *" (or a "const char *") produces a warning.
* Ugh! (It also blows up if the "__far" comes before the "void". Huh?)
*/
int
bdosptr(int code, const void __far *ptr, int subcode)
{
union _REGS regs;
struct _SREGS segregs;
regs.h.ah = code;
regs.h.al = subcode;
regs.x.dx = _FP_OFF(ptr);
segregs.ds = _FP_SEG(ptr);
_intdosx(®s, ®s, &segregs);
return regs.x.cflag ? -1 : regs.x.ax;
}
#endif /* !__BORLANDC__ */
/*
* The registers are passed in the following order.
* If ax bit 15 (ah bit 7) is CLEAR, it's a disk error.
* ah bit 0 is 1 if a write error; 0 if a read error.
* ah bits 1 and 2 identify the area of the disk with the error:
* 0 (00) for DOS area
* 1 (01) for FAT
* 2 (10) for disk directory
* 3 (11) for files area
* al gives the drive code (0 = a:, 1 = b:, etc.)
*
* If ax bit 15 (ah bit 7) is SET, it's a non-disk error.
* Either a character device error or a corrupted in-memory FAT.
* In this case, the rest of ax is meaningless.
*
* In either case, the bottom half of di gives the driver error code.
* bp:si point to the device driver header responsible
*
* If a character device, examine the device attribute word at bp:si+4.
* If bit 15 is set (character device), you can use the name field.
* Device driver header:
* Offset Len Purpose
* 0 4 Next device link (-1 if no others)
* 4 2 Device flags
* 6 2 Strategy function
* 8 2 Interrupt function
* 10 8 Device name (space-padded)
*
* Flag bits:
* 0 - standard input device
* 1 - standard output device
* 2 - Null devoce
* 3 - Clock device
* 4 - Sepcial
* 5-10 Reserved, MBZ
* 11 - Device supports removable media
* 12 - Reserved, MBZ
* 13 - Non-IBM format
* 14 - IOCTL
* 15 - Character device
*
* A DOS CRITICAL ERROR HANDLER MAY ONLY USE DOS FUNCTIONS 0-12!
* Return code is: 0 = _HARDERR_IGNORE, 1 = _HARDERR_RETRY,
* 2 = _HARDERR_ABORT (int 23), 3 = _HARDERR_FAIL (DOS 3+).
*/
void __far
hardErrHandler(unsigned di, unsigned ax, unsigned __far *devhdr)
{
char buf[64];
int i;
di &= 0xff;
sprintf(buf, "\r\nDos error %d: $", di);
bdosptr(9, buf, 0);
if (di >= sizeof(doserrs)/sizeof(*doserrs))
di = sizeof(doserrs)/sizeof(*doserrs) - 1;
bdosptr(9, doserrs[di], 0);
bdosptr(9, "\r\n$", 0);
if (ax & 0x8000) { /* Disk error */
sprintf(buf, "%s %s of drive %c:\r\n$",
readwrite[ax>>8 & 1], area[ax>>9 & 3], 'A' + ax & 255);
bdosptr(9, buf, 0);
} else {
if (FP_SEG(devhdr)+1 && FP_OFF(devhdr)+1
&& (devhdr[2] & 0x8000)) {
/* Character device */
i = 8;
while (((char __far *)devhdr)[10+--i] && i)
;
sprintf(buf, "Accessing device \"%.*s\"\r\n$",
i, ((char __far *)devhdr)+10);
bdosptr(9, buf, 0);
} else {
/* Error with in-memory FAT */
bdosptr(9, "Accessing in-memory"\
" file allocation table.\r\n$", 0);
}
}
_hardresume(_HARDERR_FAIL);
}
#endif /* MSDOS */
static int exitSigpipeCount = 0;
static void
exitBreak (int sig)
{
int code = PGPEXIT_SIGNAL;
#ifdef SIGPIPE
if (sig == SIGPIPE && ++exitSigpipeCount < 5) {
(void)signal (sig, exitBreak);
return;
}
#endif
#ifdef SIGINT
if (sig == SIGINT) {
fputs ("\nStopped at user request.\n", stderr);
code = PGPEXIT_BREAK;
} else
#endif
#ifdef SIGABRT
if (sig == SIGABRT) {
fputs ("\nInternal error.\n", stderr);
code = PGPEXIT_INTERNAL;
} else
#endif
fprintf (stderr, "\nReceived signal %d.\n", sig);
exitCleanup (code);
}
/* The signals to trap */
static int const
sigTable[] = {
#ifndef EXPIRY_DATE /* Do NOT trap on beta versions */
#ifdef SIGABRT
SIGABRT,
#endif
#endif
#ifdef SIGALRM
SIGALRM,
#endif
#ifdef SIGBUS
SIGBUS,
#endif
#ifdef SIGEMT
SIGEMT,
#endif
#ifdef SIGFPE
SIGFPE,
#endif
#ifdef SIGHUP
SIGHUP,
#endif
#ifdef SIGILL
SIGILL,
#endif
#ifdef SIGINT
SIGINT,
#endif
#if defined(SIGIOT) && SIGIOT != SIGABRT
SIGIOT,
#endif
#ifdef SIGPIPE
SIGPIPE,
#endif
#ifdef SIGQUIT
SIGQUIT,
#endif
#ifdef SIGSEGV
SIGSEGV,
#endif
#ifdef SIGSYS
SIGSYS,
#endif
#ifdef SIGTERM
SIGTERM,
#endif
#ifdef SIGTRAP
SIGTRAP,
#endif
#ifdef SIGXCPU
SIGXCPU,
#endif
#ifdef SIGXFSZ
SIGXFSZ,
#endif
-1 /* Terminate list */
};
void
exitSetup (struct PgpEnv *env, void *stacktop, void *heaptop, int prog,
int newvers)
{
int i;
for (i = 0; sigTable[i] >= 0; i++) {
if (signal (sigTable[i], SIG_IGN) != SIG_IGN)
(void)signal (sigTable[i], exitBreak);
}
program_name = prog;
env0 = env;
stack0 = stacktop;
newversion = newvers;
#if defined(UNIX) || defined(__BORLANDC__)
heap0 = heaptop;
#endif
#ifdef MSDOS
_harderr(hardErrHandler);
#endif
}
void SetProgramName(int prog)
{
program_name = prog;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -