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