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 + -
显示快捷键?