uulib.c
来自「UUDeview是一个编码解码器」· C语言 代码 · 共 1,274 行 · 第 1/2 页
C
1,274 行
/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. *//* * This file implements the externally visible functions, as declared * in uudeview.h, and some internal interfacing functions */#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef SYSTEM_WINDLL#include <windows.h>#endif#ifdef SYSTEM_OS2#include <os2.h>#endif#include <sys/types.h>#include <sys/stat.h>#include <stdio.h>#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#ifdef STDC_HEADERS#include <stdlib.h>#include <stdarg.h>#include <string.h>#else#ifdef HAVE_STDARG_H#include <stdarg.h>#else#ifdef HAVE_VARARGS_H#include <varargs.h>#endif#endif#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#ifdef HAVE_ERRNO_H#include <errno.h>#endif/* to get open() in Windows */#ifdef HAVE_IO_H#include <io.h>#endif#include <uudeview.h>#include <uuint.h>#include <fptools.h>#include <uustring.h>char * uulib_id = "$Id: uulib.c,v 1.28 2003/09/29 23:27:47 fp Exp $";#ifdef SYSTEM_WINDLLBOOL _export WINAPI DllEntryPoint (HINSTANCE hInstance, DWORD seginfo, LPVOID lpCmdLine){ /* Don't do anything, so just return true */ return TRUE;}#endif/* * In DOS, we must open the file binary, O_BINARY is defined there */#ifndef O_BINARY#define O_BINARY 0#endif/* for braindead systems */#ifndef SEEK_SET#ifdef L_BEGIN#define SEEK_SET L_BEGIN#else#define SEEK_SET 0#endif#endif/* * Callback functions and their opaque arguments */void (*uu_MsgCallback) _ANSI_ARGS_((void *, char *, int)) = NULL;int (*uu_BusyCallback) _ANSI_ARGS_((void *, uuprogress *)) = NULL;int (*uu_FileCallback) _ANSI_ARGS_((void *, char *, char *, int)) = NULL;char * (*uu_FNameFilter) _ANSI_ARGS_((void *, char *)) = NULL;void *uu_MsgCBArg = NULL;void *uu_BusyCBArg = NULL;void *uu_FileCBArg = NULL;void *uu_FFCBArg = NULL;/* * Global variables */int uu_fast_scanning = 0; /* assumes at most 1 part per file */int uu_bracket_policy = 0; /* gives part numbers in [] higher priority */int uu_verbose = 1; /* enables/disables messages¬es */int uu_desperate = 0; /* desperate mode */int uu_ignreply = 0; /* ignore replies */int uu_debug = 0; /* debugging mode (print __FILE__/__LINE__) */int uu_errno = 0; /* the errno that caused this UURET_IOERR */int uu_dumbness = 0; /* switch off the program's intelligence */int uu_overwrite = 1; /* whether it's ok to overwrite ex. files */int uu_ignmode = 0; /* ignore the original file mode */int uu_handletext = 0; /* do we want text/plain messages */int uu_usepreamble = 0; /* do we want Mime preambles/epilogues */int uu_tinyb64 = 0; /* detect short B64 outside of MIME */int uu_remove_input = 0; /* remove input files after decoding */int uu_more_mime = 0; /* strictly adhere to MIME headers */headercount hlcount = { 3, /* restarting after a MIME body */ 2, /* after useful data in freestyle mode */ 1 /* after useful data and an empty line */};/* * version string */char uulibversion[256] = VERSION "pl" PATCH;/* * prefix to the files on disk, usually a path name to save files to */char *uusavepath;/* * extension to use when encoding single-part files */char *uuencodeext;/* * areas to malloc */char *uulib_msgstring;char *uugen_inbuffer;char *uugen_fnbuffer;/* * The Global List of Files */uulist *UUGlobalFileList = NULL;/* * time values for BusyCallback. msecs is MILLIsecs here */static long uu_busy_msecs = 0; /* call callback function each msecs */static long uu_last_secs = 0; /* secs of last call to callback */static long uu_last_usecs = 0; /* usecs of last call to callback *//* * progress information */uuprogress progress;/* * Linked list of files we want to delete after decoding */typedef struct _itbd { char *fname; struct _itbd *NEXT;} itbd;static itbd * ftodel = NULL;/* * for the busy poll */unsigned long uuyctr;/* * Areas to allocate. Instead of using static memory areas, we malloc() * the memory in UUInitialize() and release them in UUCleanUp to prevent * blowing up of the binary size * This is a table with the pointers to allocate and required sizes. * They are guaranteed to be never NULL. */typedef struct { char **ptr; size_t size;} allomap;static allomap toallocate[] = { { &uugen_fnbuffer, 1024 }, /* generic filename buffer */ { &uugen_inbuffer, 1024 }, /* generic input data buffer */ { &uucheck_lastname, 256 }, /* from uucheck.c */ { &uucheck_tempname, 256 }, { &uuestr_itemp, 256 }, /* from uuencode.c:UUEncodeStream() */ { &uuestr_otemp, 1024 }, { &uulib_msgstring, 1024 }, /* from uulib.c:UUMessage() */ { &uuncdl_fulline, 300 }, /* from uunconc.c:UUDecodeLine() */ { &uuncdp_oline, 1200 }, /* from uunconc.c:UUDecodePart() */ { &uunconc_UUxlat, 256 * sizeof (int) }, /* from uunconc.c:toplevel */ { &uunconc_UUxlen, 64 * sizeof (int) }, { &uunconc_B64xlat, 256 * sizeof (int) }, { &uunconc_XXxlat, 256 * sizeof (int) }, { &uunconc_BHxlat, 256 * sizeof (int) }, { &uunconc_save, 3*300 }, /* from uunconc.c:decoding buffer */ { &uuscan_shlline, 1024 }, /* from uuscan.c:ScanHeaderLine() */ { &uuscan_shlline2, 1024 }, /* from uuscan.c:ScanHeaderLine() */ { &uuscan_pvvalue, 300 }, /* from uuscan.c:ParseValue() */ { &uuscan_phtext, 300 }, /* from uuscan.c:ParseHeader() */ { &uuscan_sdline, 300 }, /* from uuscan.c:ScanData() */ { &uuscan_sdbhds1, 300 }, { &uuscan_sdbhds2, 300 }, { &uuscan_spline, 300 }, /* from uuscan.c:ScanPart() */ { &uuutil_bhwtmp, 300 }, /* from uuutil.c:UUbhwrite() */ { NULL, 0 }};/* * Handle the printing of messages. Works like printf. */#if defined(STDC_HEADERS) || defined(HAVE_STDARG_H)intUUMessage (char *file, int line, int level, char *format, ...)#elseintUUMessage (va_alist) va_dcl#endif{ char *msgptr;#if defined(STDC_HEADERS) || defined(HAVE_STDARG_H) va_list ap; va_start (ap, format);#else char *file, *format; int line, level; va_list ap; va_start (ap); file = va_arg (ap, char *); line = va_arg (ap, int); level = va_arg (ap, int); format = va_arg (ap, char *);#endif if (uu_debug) { sprintf (uulib_msgstring, "%s(%d): %s", file, line, msgnames[level]); msgptr = uulib_msgstring + strlen (uulib_msgstring); } else { sprintf (uulib_msgstring, "%s", msgnames[level]); msgptr = uulib_msgstring + strlen (uulib_msgstring); } if (uu_MsgCallback && (level>UUMSG_NOTE || uu_verbose)) { vsprintf (msgptr, format, ap); (*uu_MsgCallback) (uu_MsgCBArg, uulib_msgstring, level); } va_end (ap); return UURET_OK;}/* * Call the Busy Callback from time to time. This function must be * polled from the Busy loops. */intUUBusyPoll (void){#ifdef HAVE_GETTIMEOFDAY struct timeval tv; long msecs; if (uu_BusyCallback) { (void) gettimeofday (&tv, NULL); msecs = 1000*(tv.tv_sec-uu_last_secs)+(tv.tv_usec-uu_last_usecs)/1000; if (uu_last_secs==0 || msecs > uu_busy_msecs) { uu_last_secs = tv.tv_sec; uu_last_usecs = tv.tv_usec; return (*uu_BusyCallback) (uu_BusyCBArg, &progress); } }#else time_t now; long msecs; if (uu_BusyCallback) { if (uu_busy_msecs <= 0) { msecs = 1; } else { now = time(NULL); msecs = 1000 * (now - uu_last_secs); } if (uu_last_secs==0 || msecs > uu_busy_msecs) { uu_last_secs = now; uu_last_usecs = 0; return (*uu_BusyCallback) (uu_BusyCBArg, &progress); } }#endif return 0;}/* * Initialization function */int UUEXPORTUUInitialize (void){ allomap *aiter; progress.action = 0; progress.curfile[0] = '\0'; ftodel = NULL; uusavepath = NULL; uuencodeext = NULL; mssdepth = 0; memset (&localenv, 0, sizeof (headers)); memset (&sstate, 0, sizeof (scanstate)); nofnum = 0; mimseqno = 0; lastvalid = 0; lastenc = 0; uuyctr = 0; /* * Allocate areas */ for (aiter=toallocate; aiter->ptr; aiter++) *(aiter->ptr) = NULL; for (aiter=toallocate; aiter->ptr; aiter++) { if ((*(aiter->ptr) = (char *) malloc (aiter->size)) == NULL) { /* * oops. we may not print a message here, because we need these * areas (uulib_msgstring) in UUMessage() */ for (aiter=toallocate; aiter->ptr; aiter++) { _FP_free (*(aiter->ptr)); } return UURET_NOMEM; } } /* * Must be called after areas have been malloced */ UUInitConc (); return UURET_OK;}/* * Set and get Options */int UUEXPORTUUGetOption (int option, int *ivalue, char *cvalue, int clength){ int result; switch (option) { case UUOPT_VERSION: _FP_strncpy (cvalue, uulibversion, clength); result = 0; break; case UUOPT_FAST: if (ivalue) *ivalue = uu_fast_scanning; result = uu_fast_scanning; break; case UUOPT_DUMBNESS: if (ivalue) *ivalue = uu_dumbness; result = uu_dumbness; break; case UUOPT_BRACKPOL: if (ivalue) *ivalue = uu_bracket_policy; result = uu_bracket_policy; break; case UUOPT_VERBOSE: if (ivalue) *ivalue = uu_verbose; result = uu_verbose; break; case UUOPT_DESPERATE: if (ivalue) *ivalue = uu_desperate; result = uu_desperate; break; case UUOPT_IGNREPLY: if (ivalue) *ivalue = uu_ignreply; result = uu_ignreply; break; case UUOPT_DEBUG: if (ivalue) *ivalue = uu_debug; result = uu_debug; break; case UUOPT_ERRNO: if (ivalue) *ivalue = uu_errno; result = uu_errno; break; case UUOPT_OVERWRITE: if (ivalue) *ivalue = uu_overwrite; result = uu_overwrite; break; case UUOPT_SAVEPATH: _FP_strncpy (cvalue, uusavepath, clength); result = 0; break; case UUOPT_PROGRESS: if (clength==sizeof(uuprogress)) { memcpy (cvalue, &progress, sizeof (uuprogress)); result = 0; } else result = -1; break; case UUOPT_IGNMODE: if (ivalue) *ivalue = uu_ignmode; result = uu_ignmode; break; case UUOPT_USETEXT: if (ivalue) *ivalue = uu_handletext; result = uu_handletext; break; case UUOPT_PREAMB: if (ivalue) *ivalue = uu_usepreamble; result = uu_usepreamble; break; case UUOPT_TINYB64: if (ivalue) *ivalue = uu_tinyb64; result = uu_tinyb64; break; case UUOPT_ENCEXT: _FP_strncpy (cvalue, uuencodeext, clength); result = 0; break; case UUOPT_REMOVE: if (ivalue) *ivalue = uu_remove_input; result = uu_remove_input; break; case UUOPT_MOREMIME: if (ivalue) *ivalue = uu_more_mime; result = uu_more_mime; break; default: return -1; } return result;}int UUEXPORTUUSetOption (int option, int ivalue, char *cvalue){ switch (option) { case UUOPT_FAST: uu_fast_scanning = ivalue; break; case UUOPT_DUMBNESS: uu_dumbness = ivalue; break; case UUOPT_BRACKPOL: uu_bracket_policy = ivalue; break; case UUOPT_VERBOSE: uu_verbose = ivalue; break; case UUOPT_DESPERATE: uu_desperate = ivalue; break; case UUOPT_IGNREPLY: uu_ignreply = ivalue; break; case UUOPT_DEBUG: uu_debug = ivalue; break; case UUOPT_OVERWRITE: uu_overwrite = ivalue; break; case UUOPT_SAVEPATH: _FP_free (uusavepath); uusavepath = _FP_strdup (cvalue); break; case UUOPT_IGNMODE: uu_ignmode = ivalue; break; case UUOPT_USETEXT: uu_handletext = ivalue; break; case UUOPT_PREAMB: uu_usepreamble = ivalue; break; case UUOPT_TINYB64: uu_tinyb64 = ivalue; break; case UUOPT_ENCEXT: _FP_free (uuencodeext); uuencodeext = _FP_strdup (cvalue); break; case UUOPT_REMOVE: uu_remove_input = ivalue; break; case UUOPT_MOREMIME: uu_more_mime = ivalue; break; default: return UURET_ILLVAL; } return UURET_OK;}char * UUEXPORTUUstrerror (int code){ return uuretcodes[code];}/* * Set the various Callback functions */int UUEXPORTUUSetMsgCallback (void *opaque, void (*func) _ANSI_ARGS_((void *, char *, int))){ uu_MsgCallback = func; uu_MsgCBArg = opaque; return UURET_OK;}int UUEXPORTUUSetBusyCallback (void *opaque, int (*func) _ANSI_ARGS_((void *, uuprogress *)), long msecs){ uu_BusyCallback = func; uu_BusyCBArg = opaque; uu_busy_msecs = msecs; return UURET_OK;}int UUEXPORTUUSetFileCallback (void *opaque, int (*func) _ANSI_ARGS_((void *, char *, char *, int))){ uu_FileCallback = func; uu_FileCBArg = opaque; return UURET_OK;}int UUEXPORTUUSetFNameFilter (void *opaque, char * (*func) _ANSI_ARGS_((void *, char *))){ uu_FNameFilter = func; uu_FFCBArg = opaque; return UURET_OK;}/* * Return a pointer to the nth element of the GlobalFileList * zero-based, returns NULL if item is too large. */uulist * UUEXPORTUUGetFileListItem (int item){ uulist *iter=UUGlobalFileList; if (item < 0) return NULL; while (item && iter) { iter = iter->NEXT; item--; } return iter;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?