uuscan.c

来自「UUDeview是一个编码解码器」· C语言 代码 · 共 2,492 行 · 第 1/5 页

C
2,492
字号
      *errcode = UURET_NOMEM;      _FP_free (result);      return NULL;    }    /* ignore empty lines at the beginning of a file */    preheaders = ftell (datei);    while (!feof (datei)) {      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();      if (_FP_fgets (line, 255, datei) == NULL)	break;      line[255] = '\0';      if (!IsLineEmpty (line)) {	fseek (datei, preheaders, SEEK_SET);	break;      }      preheaders = ftell (datei);    }  }  if (ferror(datei) || feof(datei)) {    _FP_free (result);    return NULL;  }  /*   * If we are confident that this is a mail folder and are at the   * beginning of the file, expecting to read some headers, scan   * the envelope.   */  if (sstate.isfolder && sstate.mimestate == MS_HEADERS) {    hcount = 0;    lcount = 0;    UUkillheaders (&sstate.envelope);    /*     * clean up leftovers from invalid messages     */    while (mssdepth) {      mssdepth--;      UUkillheaders (&(multistack[mssdepth].envelope));      _FP_free (multistack[mssdepth].source);    }    prevpos = ftell (datei);    if (_FP_fgets (line, 255, datei) == NULL) {      _FP_free (result);      return NULL;    }    line[255] = '\0';    /*     * Special handling for AOL folder files, which start off with a boundary.     * We recognize them by a valid boundary line as the first line of a file.     * Note that the rest of the scanning code becomes suspicious if a boun-     * dary does never appear in a file -- this should save us from grave     * false detection errors     */    if (!feof (datei) && line[0] == '-' && line[1] == '-' && line[2]) {      while (line[strlen(line)-1] == '\012' ||	     line[strlen(line)-1] == '\015') {	line[strlen(line)-1] = '\0';      }      sstate.ismime            = 1;      sstate.envelope.mimevers = _FP_strdup ("1.0");      sstate.envelope.boundary = _FP_strdup (line+2);      sstate.envelope.ctype    = _FP_strdup ("multipart/mixed");      sstate.mimestate         = MS_SUBPART;      *errcode = UURET_CONT;      _FP_free (result);      return NULL;    }    /*     * Normal behavior: look for a RFC 822 header     */    while (!feof (datei) && !IsLineEmpty (line)) {      if (IsKnownHeader (line))	hcount++;      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();      if (IsHeaderLine (line)) {	ptr1 = ScanHeaderLine (datei, line);	if (ParseHeader (&sstate.envelope, ptr1) == NULL) {	  *errcode = UURET_NOMEM;	  _FP_free (result);	  return NULL;	}      }      /*       * if we've read too many lines without finding headers, then       * this probably isn't a mail folder after all       */      lcount++;      if (lcount > WAITHEADER && hcount < hlcount.afternl) {	fseek (datei, prevpos, SEEK_SET);	line[0] = '\0';	break;      }      if (_FP_fgets (line, 255, datei) == NULL)	break;      line[255] = '\0';    }    /* skip empty lines */    prevpos = ftell (datei);    if (IsLineEmpty (line)) {      while (!feof (datei)) {	if (_FP_fgets (line, 255, datei) == NULL)	  break;	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();	if (!IsLineEmpty (line)) {	  fseek (datei, prevpos, SEEK_SET);	  line[255] = '\0';	  break;	}	prevpos = ftell (datei);      }    }    /*     * If we don't have all valid MIME headers yet, but the following     * line is a MIME header, accept it anyway.     */    if (!uu_more_mime &&	sstate.envelope.mimevers == NULL &&	sstate.envelope.ctype    == NULL &&	sstate.envelope.ctenc    == NULL &&	IsKnownHeader (line)) {      /*       * see above       */      if (_FP_fgets (line, 255, datei) == NULL) {	line[0] = '\012';	line[1] = '\0';      }      line[255] = '\0';      while (!feof (datei) && !IsLineEmpty (line)) {	if (IsKnownHeader (line))	  hcount++;	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();	ptr1 = ScanHeaderLine (datei, line);	if (ParseHeader (&sstate.envelope, ptr1) == NULL) {	  *errcode = UURET_NOMEM;	  _FP_free (result);	  return NULL;	}	if (_FP_fgets (line, 255, datei) == NULL)	  break;	line[255] = '\0';      }      /* skip empty lines */      prevpos = ftell (datei);      while (!feof (datei)) {	if (_FP_fgets (line, 255, datei) == NULL)	  break;	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();	if (!IsLineEmpty (line)) {	  fseek (datei, prevpos, SEEK_SET);	  line[255] = '\0';	  break;	}	prevpos = ftell (datei);      }    }    /*     * A partial multipart message probably has only a Content-Type     * header but nothing else. In this case, at least simulate a     * MIME message     * if mimevers is not set but there are other well-known MIME     * headers, don't be too picky about it.     */    if (sstate.envelope.ctype && sstate.envelope.mimevers==NULL  &&	_FP_stristr (sstate.envelope.ctype, "multipart") != NULL &&	sstate.envelope.boundary != NULL) {      sstate.envelope.mimevers = _FP_strdup ("1.0");      hcount = hlcount.afternl;    }    else if (sstate.envelope.mimevers==NULL && sstate.envelope.ctype &&	     sstate.envelope.fname && sstate.envelope.ctenc) {      sstate.envelope.mimevers = _FP_strdup ("1.0");      hcount = hlcount.afternl;    }    if (sstate.envelope.mimevers != NULL) {      /* this is a MIME file. check the Content-Type */      sstate.ismime = 1;      if (_FP_stristr (sstate.envelope.ctype, "multipart") != NULL) {	if (sstate.envelope.boundary == NULL) {	  UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,		     uustring (S_MIME_NO_BOUNDARY));	  sstate.mimestate = MS_BODY;	  _FP_free (sstate.envelope.ctype);	  sstate.envelope.ctype = _FP_strdup ("text/plain");	}	else {	  sstate.mimestate = MS_PREAMBLE;	}      }      else {	sstate.mimestate = MS_BODY;	/* just a `simple' message */      }    }    else {      /* not a folder after all */      fseek (datei, prevpos, SEEK_SET);      sstate.isfolder = 0;      sstate.ismime   = 0;    }  }  if (feof (datei) || ferror (datei)) { /* oops */    _FP_free (result);    return NULL;  }  /*   * Handle MIME stuff   */  /*   * Read Preamble. This must be ended by a sstate.envelope.boundary line.   * If uu_usepreamble is set, we produce a result from this one   */  if (sstate.ismime && sstate.mimestate == MS_PREAMBLE) {    result->startpos = ftell (datei);	/* remember start of preamble */    prevpos          = ftell (datei);    preheaders       = ftell (datei);    blen   = strlen (sstate.envelope.boundary);    lcount = 0;        while (!feof (datei)) {      if (_FP_fgets (line, 255, datei) == NULL) {	line[0] = '\0';	break;      }      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();      if (line[0] == '-' && line[1] == '-' &&	  strncmp (line+2, sstate.envelope.boundary, blen) == 0)	break;      if (!IsLineEmpty (line))	lcount++;      prevpos = ftell (datei);    }    if (feof (datei) || ferror (datei)) {      UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,		 uustring (S_MIME_B_NOT_FOUND));      /*       * restart and try again; don't restart if uu_fast_scanning       */      sstate.isfolder  = 0;      sstate.ismime    = 0;      sstate.mimestate = MS_BODY;      if (!uu_fast_scanning) {	*errcode = UURET_CONT;	fseek (datei, preheaders, SEEK_SET);      }      _FP_free (result);      return NULL;    }    if (line[0] == '-' && line[1] == '-' &&	strncmp (line+2, sstate.envelope.boundary, blen) == 0) {      ptr1 = line + 2 + blen;      if (*ptr1 == '-' && *(ptr1+1) == '-') {	/* Empty Multipart Message. Duh. */	sstate.mimestate = MS_EPILOGUE;      }      else {	sstate.mimestate = MS_SUBPART;      }    }    else { /* shouldn't happen */      UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,		 uustring (S_MIME_B_NOT_FOUND));      /*       * restart and try again; don't restart if uu_fast_scanning       */      sstate.isfolder  = 0;      sstate.ismime    = 0;      sstate.mimestate = MS_BODY;      if (!uu_fast_scanning) {	*errcode = UURET_CONT;	fseek (datei, preheaders, SEEK_SET);      }      _FP_free (result);      return NULL;    }    /* produce result if uu_usepreamble is set */    if (uu_usepreamble && lcount) {      sprintf (line, "%04d.txt", ++mimseqno);      result->subject  = _FP_strdup (sstate.envelope.subject);      result->filename = _FP_strdup (line);      result->origin   = _FP_strdup (sstate.envelope.from);      result->mimeid   = _FP_strdup (sstate.envelope.mimeid);      result->mimetype = _FP_strdup ("text/plain");      result->mode     = 0644;      result->uudet    = PT_ENCODED;	/* plain text */      result->sfname   = _FP_strdup (fname);      result->flags    = FL_SINGLE | FL_PROPER;      /* result->startpos set from above */      result->length   = prevpos - result->startpos;      result->partno   = 1;      /* MIME message, let's continue */      *errcode = UURET_CONT;      if ((sstate.envelope.subject != NULL && result->subject == NULL) ||	  result->filename == NULL || result->sfname == NULL) {	*errcode = UURET_NOMEM;      }      return result;    }    /* MIME message, let's continue */    if (*errcode == UURET_OK)      *errcode = UURET_CONT;    /* otherwise, just return NULL */    _FP_free (result);    return NULL;  }  /*   * Read Epilogue, the plain text after the last boundary.   * This can either end with new headers from the next message of a   * mail folder or with a `parent' boundary if we are inside an   * encapsulated Multipart message. Oh yes, and of course the file   * may also simply end :-)   * Another possibility is that we might find plain encoded data   * without encapsulating message. We're not _too_ flexible here,   * we won't detect Base64, and require a proper `begin' line for   * uuencoding and xxencoding   * If uu_usepreamble is set, we produce a result from this one   */  if (sstate.ismime && sstate.mimestate == MS_EPILOGUE) {    result->startpos = ftell (datei);	/* remember start of epilogue */    prevpos          = ftell (datei);    preheaders       = ftell (datei);    preenc           = ftell (datei);    hcount = lcount  = 0;    ecount = bhflag  = 0;    begflag = vflag  = 0;    res = 0;    /*     * If we are in the outermost message and uu_fast_scanning, we     * know (or assume) that no more messages will follow, so there's     * no need to scan the rest.     */    if (uu_fast_scanning && mssdepth == 0) {      /*       * check if the epilogue is empty       */      while (!feof (datei) && !ferror (datei) && lcount<10 && res==0) {	if (_FP_fgets (line, 255, datei) == NULL)	  break;	if (!IsLineEmpty (line))	  res++;	lcount++;      }      if (uu_usepreamble && res) {	sprintf (line, "%04d.txt", ++mimseqno);	result->subject  = _FP_strdup (sstate.envelope.subject);	result->filename = _FP_strdup (line);	result->origin   = _FP_strdup (sstate.envelope.from);	result->mimeid   = _FP_strdup (sstate.envelope.mimeid);	result->mimetype = _FP_strdup ("text/plain");	result->mode     = 0644;	result->uudet    = PT_ENCODED;	/* plain text */	result->sfname   = _FP_strdup (fname);	result->flags    = FL_SINGLE | FL_PROPER | FL_TOEND;	result->partno   = 1;	/* result->startpos set from above */	result->length   = progress.fsize - result->startpos;	if ((sstate.envelope.subject != NULL && result->subject == NULL) ||	    result->filename == NULL || result->sfname == NULL) {	  *errcode = UURET_NOMEM;	}	return result;      }      _FP_free (result);      return NULL;    }    if (mssdepth > 0)      blen = strlen (multistack[mssdepth-1].envelope.boundary);    while (!feof (datei)) {      if (_FP_fgets (line, 255, datei) == NULL) {	line[0] = '\0';	break;      }      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();      line[255] = '\0';      /* check for parent boundary */      if (mssdepth > 0 && line[0] == '-' && line[1] == '-' &&	  strncmp (line+2,		   multistack[mssdepth-1].envelope.boundary, blen) == 0)	break;      /* check for next headers only at outermost level */      if (mssdepth == 0 && IsKnownHeader (line)) {	(void) ScanHeaderLine (datei, line);	if (hcount == 0) {	  preheaders = prevpos;	  lcount     = 0;	}	hcount++; 	lcount++;	if (hcount >= hlcount.restart) {	  /* okay, new headers */	  break;	}      }      else if (lcount > WAITHEADER) {	hcount = 0;	lcount = 0;      }      else if (hcount) {	lcount++;      }      else {	hcount = lcount = 0;      }      /* check for begin and encoded data only at outermost level */      if (mssdepth == 0 && !uu_more_mime) {	if (strncmp      (line, "begin ",       6) == 0 ||	    _FP_strnicmp (line, "<pre>begin ", 11) == 0) {	  preenc  = prevpos;	  begflag = 1;	}	else if (strncmp (line, "end", 3) == 0 && begflag) {	  ecount = ELC_COUNT;	  break;	}	else if ((vflag = UUValidData (line, 0, &bhflag)) != 0) {	  if (vflag == BH_ENCODED && bhflag == 0) {	    /* very short BinHex file follows */	    preenc = prevpos;	    break;	  }	  /* remember that XX can easily be mistaken as Base64 */	  if ((vflag == UU_ENCODED || vflag == XX_ENCODED ||	       vflag == B64ENCODED) && begflag) {	    if (++ecount >= ELC_COUNT)	      break;	  }	  else {	    begflag = 0;	    ecount  = 0;	  }	}	else {	  begflag = 0;	  ecount  = 0;	}      }      if (!IsLineEmpty (line))	res++;      prevpos = ftell (datei);    }    if (mssdepth > 0 &&	line[0] == '-' && line[1] == '-' &&	strncmp (line+2,		 multistack[mssdepth-1].envelope.boundary, blen) == 0) {      /* restore previous state */      mssdepth--;      UUkillheaders (&sstate.envelope);      _FP_free  (sstate.source);      memcpy (&sstate, &(multistack[mssdepth]), sizeof (scanstate));      ptr1 = line + 2 + strlen (sstate.envelope.boundary);      if (*ptr1 == '-' && *(ptr1+1) == '-') {	sstate.mimestate = MS_EPILOGUE;      }      else {	sstate.mimestate = MS_SUBPART;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?