📄 uudeview.c
字号:
/* * 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. */#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>#include <ctype.h>#include <signal.h>#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#ifdef STDC_HEADERS#include <stdlib.h>#include <string.h>#endif#ifdef HAVE_MALLOC_H#include <malloc.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_MEMORY_H#include <memory.h>#endif#ifdef HAVE_ERRNO_H#include <errno.h>#endif#include <uudeview.h>#include <fptools.h>#include <uufnflt.h>/* For the sake of getcwd() in DOS */#ifdef HAVE_DIRECT_H#include <direct.h>#endif/* * the progress meter is only displayed if stderr is a terminal. * take care of systems where we can't check this condition. */#ifdef HAVE_ISATTY#define UUISATTY(f) (isatty(fileno(f)))#else#define UUISATTY(f) (1)#endif#define SHOW_INFO (1) /* For more () */#define SHOW_FILE (2)/* * local definitions */typedef struct _extlist { char extension[8]; struct _extlist *NEXT;} extlist;/* * Operational Flags */static int incext = 0, stdinput = 0;static int overwrite = 0, interact = 1;static int quiet = 0, decoall = 0;static int nobar = 0, autoren = 0;/* * Global Variables */static extlist *extensions = NULL;static char savepath[512];/* * some statistics */static int decodedok = 0;static int decodedfailed = 0;static int decodedmisp = 0;static int inputerrors = 0;static int inputfiles = 0;/* * version string */static char uuversion[256] = VERSION "pl" PATCH;/* * cvs version */char * uudeview_id = "$Id: uudeview.c,v 1.28 2003/04/12 23:33:55 fp Exp $";static int addexts _ANSI_ARGS_((char *));static int work_file _ANSI_ARGS_((char *));static int proc_stdin _ANSI_ARGS_((void));static void loadparfile _ANSI_ARGS_((char *));static int work_comline _ANSI_ARGS_((int, char *[]));static int moreCB _ANSI_ARGS_((void *, char *));static void more _ANSI_ARGS_((uulist *, int));static void DumpFileList _ANSI_ARGS_((void));static int process_one _ANSI_ARGS_((uulist *));static int process_files _ANSI_ARGS_((void));static void sighandler _ANSI_ARGS_((int));static void usage _ANSI_ARGS_((char *));/* * Header lines starting with these texts will be stripped when * printing a file's info */static char *hateheaders[] = { "Path:", "Newsgroups:", /*"Organization:",*/ "Lines:", "Message-ID:", "NNTP-Posting-Host:", "Xref:", "References:", "X-Newsreader:", "Distribution", /*"Sender:",*/ "Nntp-Posting-Host:", /*"Reply-To:",*/ /*"Approved:",*/ "Mime-Version:", "Content-Type:", "Content-Transfer-Encoding:", "X-Posting-Software:", NULL};/* * Busy Callback */static intBusyCallback (void *param, uuprogress *progress){ char stuff[26]; int count, pcts; char *ptr; /* * Display progress meter only if stderr is a terminal */ if (!UUISATTY(stderr) || nobar) return 0; if ((ptr = _FP_strrchr (progress->curfile, DIRSEPARATOR[0])) == NULL) ptr = progress->curfile; else ptr++; if (!quiet && progress->action == 1) { fprintf (stderr, "scanned %3d%% of %-50s\r", progress->percent, ptr); fflush (stderr); } else if (!quiet && progress->action == 2) { pcts = (int)((100*progress->partno+progress->percent-100) / progress->numparts); for (count=0, stuff[25]='\0'; count<25; count++) stuff[count] = (count<pcts/4)?'#':'.'; fprintf (stderr, "decoding part%3d of%3d %s\r", progress->partno, progress->numparts, stuff); fflush (stderr); } else if (!quiet && progress->action == 3) { for (count=0, stuff[25]='\0'; count<25; count++) stuff[count] = (count<progress->percent/4)?'#':'.'; fprintf (stderr, "copying target file %s\r", stuff); fflush (stderr); } return 0;}/* * Message Callback */static voidMessageCallback (void *param, char *message, int level){ if (!quiet || level >= UUMSG_WARNING) fprintf (stderr, "%s\n", message);}/* * local functions */static voidkillext (extlist *data){ extlist *iter=data, *ptr; while (iter) { ptr = iter->NEXT; _FP_free (iter); iter = ptr; }}static char *filemode (int mode){ static char result[11]; static char rwxkey[8][4] = { "---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx" }; result[0] = '-'; result[1] = rwxkey[((mode >> 6) & 0x07)][0]; result[2] = rwxkey[((mode >> 6) & 0x07)][1]; result[3] = rwxkey[((mode >> 6) & 0x07)][2]; result[4] = rwxkey[((mode >> 3) & 0x07)][0]; result[5] = rwxkey[((mode >> 3) & 0x07)][1]; result[6] = rwxkey[((mode >> 3) & 0x07)][2]; result[7] = rwxkey[ mode & 0x07 ][0]; result[8] = rwxkey[ mode & 0x07 ][1]; result[9] = rwxkey[ mode & 0x07 ][2]; result[10]= '\0'; return result;}/* * check if we want the header displayed */static intIsHeaderLine (char *text){ char **hiter = hateheaders; if (text == NULL || hiter == NULL) return 0; while (*hiter) { if (_FP_strnicmp (text, *hiter, strlen (*hiter)) == 0) return 1; hiter++; } return 0;}/* * get a character from stdin (the keyboard), or accept default */static char getyn (char *theline, char def){ char line[256], *ptr=0; int isdebug; if (interact && !feof (stdin)) { fflush (stdout); if ((ptr = _FP_fgets ((theline)?theline:line, 255, stdin)) == NULL) { if (theline) *theline='\0'; return def; } if (ptr[0]=='4'&&ptr[1]=='2') { UUGetOption (UUOPT_DEBUG, &isdebug, NULL, 0); UUSetOption (UUOPT_DEBUG, !isdebug, NULL); if (!isdebug) printf ("*** Debugging Mode On\n"); else printf ("*** Debugging Mode Off\n"); ptr+=2; } while (isspace (*ptr) && *ptr!='\n') ptr++; if (*ptr == '\n') { if (theline) *theline='\0'; return def; } } else { if (theline) *theline='\0'; printf ("%c\n", def); return def; } return tolower(*ptr);}/* * check whether a file exists or not. This check is used when we decide * if a file would be overwritten. We also overwrite files with zero * length. */static intexists (char *filename){ struct stat finfo; if (filename == NULL || *filename == '\0') return 0; if (stat (filename, &finfo) != 0) return 0; if ((long) finfo.st_size == 0) return 0; return 1;}/* * Find a new unique filename by adding a unique number to the file name. * Some want the unique name at the end, while others prefer to keep it * before the file extension. Support both. * So if autoren is positive, append the unique number at the end. If it * is negative, insert it before the first dot in the filename. */intfindAlternateName (char *originalName, char *newName, int autoren){ char *p; int i; for (i=1; i<32768; i++) { if (autoren > 0) { sprintf (newName, "%s.%d", originalName, i); } else { strcpy (newName, originalName); if ((p = strchr (newName, '.')) != NULL) { sprintf (p, "_%d%s", i, strchr (originalName, '.')); } else { sprintf (newName, "%s_%d", originalName, i); } } if (!exists (newName)) { return 1; } } return 0;}/* * Add another extension we shall or shall not decode */static int addexts (char *elist){ extlist *enew; int iter; while (*elist) { if (*elist != '.') { elist++; continue; } if (*++elist == '\0') break; if ((enew = (extlist *) malloc (sizeof (extlist))) == NULL) { fprintf (stderr, "ERROR: Out of memory in addexts()\n"); return 0; } iter = 0; while (*elist != '.' && *elist != '\0' && iter < 7) enew->extension[iter++] = *elist++; enew->extension[iter] = '\0'; enew->NEXT = extensions; extensions = enew; } return 1;}/* * looks at the extension of a file and decides whether we want to decode * it or not, based on our extensions list */static int work_file (char *filename){ extlist *iter = extensions; char *ptr; if (filename == NULL) return 0; if ((ptr = _FP_strrchr (filename, '.')) == NULL) return incext ? 0 : 1; ptr++; while (iter) { if (_FP_stricmp (ptr, iter->extension) == 0) return incext ? 1 : 0; iter = iter->NEXT; } return incext ? 0 : 1;}/* * Handle standard input. Dump it into a temporary file and then add * this temp file to our list of command-line files */static int proc_stdin (void){ static char buffer[1024]; char *stdfile; FILE *target; size_t bytes; int res; if (stdinput) { fprintf (stderr, "proc_stdin: cannot process stdin twice\n"); return 0; } if ((stdfile = tempnam (NULL, "uu")) == NULL) { fprintf (stderr, "proc_stdin: cannot get temporary file\n"); return 0; } if ((target = fopen (stdfile, "wb")) == NULL) { fprintf (stderr, "proc_stdin: cannot open temp file %s for writing: %s\n", stdfile, strerror (errno)); _FP_free (stdfile); return 0; } while (!feof (stdin)) { bytes = fread (buffer, 1, 1024, stdin); if (bytes == 0) break; if (ferror (stdin)) { fprintf (stderr, "proc_stdin: error reading from stdin: %s\n", strerror (errno)); break; } if (fwrite (buffer, 1, bytes, target) != bytes) { fprintf (stderr, "proc_stdin: cannot write to temp file %s: %s\n", stdfile, strerror (errno)); break; } if (ferror (target)) { fprintf (stderr, "proc_stdin: error writing to temp file %s: %s\n", stdfile, strerror (errno)); break; } } if (ferror (stdin) || ferror (target)) { fclose (target); unlink (stdfile); _FP_free (stdfile); return 0; } fclose (target); inputfiles++; if ((res = UULoadFile (stdfile, NULL, 1)) != UURET_OK) { fprintf (stderr, "ERROR: while reading from copied standard input %s: %s %s\n", stdfile, UUstrerror (res), (res==UURET_IOERR)? strerror (UUGetOption (UUOPT_ERRNO, NULL, NULL, 0)) : ""); inputerrors = 1; } _FP_free (stdfile); stdinput = 1; return 1;}/* * extract parameters from "command line" */static voidmakeparams (char *comline){ char *p1, *argv[32]; int argc=2, quote=0; if (comline==NULL || *comline=='\0') return; p1 = comline;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -