uucheck.c
来自「UUDeview是一个编码解码器」· C语言 代码 · 共 1,469 行 · 第 1/3 页
C
1,469 行
/* * 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/* * uucheck.c * * Various checking and processing of one input part **/#include <stdio.h>#include <ctype.h>#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#include <uudeview.h>#include <uuint.h>#include <fptools.h>#include <uustring.h>char * uucheck_id = "$Id: uucheck.c,v 1.15 2003/04/13 15:41:55 fp Exp $";/* * Arbitrary number. This is the maximum number of part numbers we * store for our have-parts and missing-parts lists */#define MAXPLIST 256/* * forward declarations of local functions */static char * UUGetFileName _ANSI_ARGS_((char *, char *, char *));static int UUGetPartNo _ANSI_ARGS_((char *, char **, char **));/* * State of Scanner function and PreProcessPart */int lastvalid, lastenc, nofnum;char *uucheck_lastname;char *uucheck_tempname;static int lastpart = 0;static char *nofname = "UNKNOWN";/* * special characters we allow an unquoted filename to have */static char *fnchars = "._-~!";/* * Policy for extracting a part number from the subject line. * usually, look for part numbers in () brackets first, then in [] */static char *brackchr[] = { "()[]", "[]()"};/* * Extract a filename from the subject line. We need anything to identify * the name of the program for sorting. If a nice filename cannot be found, * the subject line itself is used * ptonum is, if not NULL, a pointer to the part number in the subject line, * so that it won't be used as filename. **/static char *UUGetFileName (char *subject, char *ptonum, char *ptonend){ char *ptr = subject, *iter, *result, *part; int count, length=0, alflag=0;/* * If this file has no subject line, assume it is the next part of the * previous file (this is done in UUPreProcessPart) **/ if (subject == NULL) return NULL;/* * If the subject starts with 'Re', it is ignored * REPosts or RETries are not ignored! **/ if (uu_ignreply && (subject[0] == 'R' || subject[0] == 'r') && (subject[1] == 'E' || subject[1] == 'e') && (subject[2] == ':' || subject[2] == ' ')) { return NULL; }/* * Ignore a "Repost" prefix of the subject line. We don't want to get * a file named "Repost" :-) **/ if (_FP_strnicmp (subject, "repost", 6) == 0) subject += 6; if (_FP_strnicmp (subject, "re:", 3) == 0) subject += 3; while (*subject == ' ' || *subject == ':') subject++; part = _FP_stristr (subject, "part"); if (part == subject) { subject += 4; while (*subject == ' ') subject++; } /* * If the file was encoded by uuenview, then the filename is enclosed * in [brackets]. But check what's inside these bracket's, try not to * fall for something other than a filename */ ptr = subject; while ((iter = strchr (ptr, '[')) != NULL) { if (strchr (iter, ']') == NULL) { ptr = iter + 1; continue; } iter++; while (isspace (*iter)) iter++; count = length = alflag = 0; while (iter[count] && (isalnum (iter[count]) || strchr (fnchars, iter[count])!=NULL)) { if (isalpha (iter[count])) alflag++; count++; } if (count<4 || alflag==0) { ptr = iter + 1; continue; } length = count; while (isspace (iter[count])) count++; if (iter[count] == ']') { ptr = iter; break; } length = 0; ptr = iter + 1; } /* * new filename detection routine, fists mostly for files by ftp-by-email * servers that create subject lines with ftp.host.address:/full/path/file * on them. We look for slashes and take the filename from after the last * one ... or at least we try to. */ if (length == 0) { ptr = subject; while ((iter = strchr (ptr, '/')) != NULL) { if (iter >= ptonum && iter <= ptonend) { ptr = iter + 1; continue; } count = length = 0; iter++; while (iter[count] && (isalnum(iter[count])||strchr(fnchars, iter[count])!=NULL)) count++; if (iter[count] == ' ' && length > 4) { length = count; break; } ptr = iter + ((count)?count:1); } } /* * Look for two alphanumeric strings separated by a '.' * (That's most likely a filename) **/ if (length == 0) { ptr = subject; while (*ptr && *ptr != 0x0a && *ptr != 0x0d && ptr != part) { iter = ptr; count = length = alflag = 0; if (_FP_strnicmp (ptr, "ftp", 3) == 0) { /* hey, that's an ftp address */ while (isalpha (*ptr) || isdigit (*ptr) || *ptr == '.') ptr++; continue; } while ((isalnum(*iter)||strchr(fnchars, *iter)!=NULL|| *iter=='/') && *iter && iter != ptonum && *iter != '.') { if (isalpha (*iter)) alflag = 1; count++; iter++; } if (*iter == '\0' || iter == ptonum) { if (iter == ptonum) ptr = ptonend; else ptr = iter; length = 0; continue; } if (*iter++ != '.' || count > 32 || alflag == 0) { ptr = iter; length = 0; continue; } if (_FP_strnicmp (iter, "edu", 3) == 0 || _FP_strnicmp (iter, "gov", 3) == 0) { /* hey, that's an ftp address */ while (isalpha (*iter) || isdigit (*iter) || *iter == '.') iter++; ptr = iter; length = 0; continue; } length += count + 1; count = 0; while ((isalnum(iter[count])||strchr(fnchars, iter[count])!=NULL|| iter[count]=='/') && iter[count] && iter[count] != '.') count++; if (iter[count]==':' && iter[count+1]=='/') { /* looks like stuff from a mail server */ ptr = iter + 1; length = 0; continue; } if (count > 8 || iter == ptonum) { ptr = iter; length = 0; continue; } if (iter[count] != '.') { length += count; break; } while (iter[count] && (isalnum(iter[count])||strchr(fnchars, iter[count])!=NULL|| iter[count]=='/')) count++; if (iter[count]==':' && iter[count+1]=='/') { /* looks like stuff from a mail server */ ptr = iter + 1; length = 0; continue; } if (count < 12 && iter != ptonum) { length += count; break; } ptr = iter; length = 0; } } if (length == 0) { /* No filename found, use subject line for ident */ ptr = subject; while (*ptr && !isalpha (*ptr)) ptr++; while ((isalnum(ptr[length])||strchr(fnchars,ptr[length])!=NULL|| ptr[length] == '/') && ptr[length] && ptr+length!=part && ptr+length!=ptonum) length++; if (length) { if (ptr[length] == '\0' || ptr[length] == 0x0a || ptr[length] == 0x0d) { length--; /* * I used to cut off digits from the end of the string, but * let's try to live without. We want to distinguish * DUTCH951 from DUTCH952 * * while ((ptr[length] == ' ' || isdigit (ptr[length])) && length > 0) * length--; */ } else { length--; while (ptr[length] == ' ' && length > 0) length--; } length++; } } if (length == 0) { /* Still found nothing? We need *something*! */ ptr = nofname; length = strlen (nofname); } if ((result = (char *) malloc (length + 1)) == NULL) { UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, uustring (S_OUT_OF_MEMORY), length+1); return NULL; } memcpy (result, ptr, length); result[length] = '\0'; return result;}/* * Extract the Part Number from the subject line. * We look first for numbers in (#/#)'s, then for numbers in [#/#]'s * and then for digits that are not part of a string. * If we cannot find anything, assume it is the next part of the * previous file. * If we find a part number, we put a pointer to it in *where. This is * done so that the UUGetFileName function doesn't accidentally use the * part number as the file name. *whend points to the end of this part * number. **/static intUUGetPartNo (char *subject, char **where, char **whend){ char *ptr = subject, *iter, *delim, bdel[2]=" "; int count, length=0, bpc; *where = NULL; bdel[0] = ' '; *whend = NULL; bdel[1] = '\0'; iter = NULL; delim = ""; if (subject == NULL) return -1; if (uu_ignreply && (subject[0] == 'R' || subject[0] == 'r') && /* Ignore replies, but not */ (subject[1] == 'E' || subject[1] == 'e') && /* reposts */ (subject[2] == ':' || subject[2] == ' ')) return -2; /* * First try numbers in () or [] (or vice versa, according to bracket * policy) */ for (bpc=0, length=0; brackchr[uu_bracket_policy][bpc]; bpc+=2) { ptr = subject; while ((iter = strchr (ptr, brackchr[uu_bracket_policy][bpc])) != NULL) { count = length = 0; iter++; while (*iter == ' ' || *iter == '#') iter++; if (!isdigit (*iter)) { ptr = iter; continue; } while (isdigit (iter[count])) count++; length = count; if (iter[count] == '\0' || iter[count+1] == '\0') { iter += count; length = 0; break; } if (iter[count] == brackchr[uu_bracket_policy][bpc+1]) { *where = iter; bdel[0] = brackchr[uu_bracket_policy][bpc+1]; delim = bdel; break; } while (iter[count] == ' ' || iter[count] == '#' || iter[count] == '/' || iter[count] == '\\') count++; if (_FP_strnicmp (iter + count, "of", 2) == 0) count += 2; while (iter[count] == ' ') count++; while (isdigit (iter[count])) count++; while (iter[count] == ' ') count++; if (iter[count] == brackchr[uu_bracket_policy][bpc+1]) { *where = iter; bdel[0] = brackchr[uu_bracket_policy][bpc+1]; delim = bdel; break; } length = 0; ptr = iter; } if (length) break; } /* * look for the string "part " followed by a number */ if (length == 0) { if ((iter = _FP_stristr (subject, "part ")) != NULL) { iter += 5; while (isspace (*iter) || *iter == '.' || *iter == '-') iter++; while (isdigit (iter[length])) length++; if (length == 0) { if (_FP_strnicmp (iter, "one", 3) == 0) length = 1; else if (_FP_strnicmp (iter, "two", 3) == 0) length = 2; else if (_FP_strnicmp (iter, "three", 5) == 0) length = 3; else if (_FP_strnicmp (iter, "four", 4) == 0) length = 4; else if (_FP_strnicmp (iter, "five", 4) == 0) length = 5; else if (_FP_strnicmp (iter, "six", 3) == 0) length = 6; else if (_FP_strnicmp (iter, "seven", 5) == 0) length = 7; else if (_FP_strnicmp (iter, "eight", 5) == 0) length = 8; else if (_FP_strnicmp (iter, "nine", 4) == 0) length = 9; else if (_FP_strnicmp (iter, "ten", 3) == 0) length = 10; if (length && (*whend = strchr (iter, ' '))) { *where = iter; return length; } else length = 0; } else { *where = iter; delim = "of"; } } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?