uulib.c
来自「UUDeview是一个编码解码器」· C语言 代码 · 共 1,274 行 · 第 1/2 页
C
1,274 行
/* * call the current filter */char * UUEXPORTUUFNameFilter (char *fname){ if (uu_FNameFilter) return (*uu_FNameFilter) (uu_FFCBArg, fname); return fname;}/* * Load a File. We call ScanPart repeatedly until at EOF and * add the parts to UUGlobalFileList */int UUEXPORTUULoadFile (char *filename, char *fileid, int delflag){ return UULoadFileWithPartNo(filename, fileid, delflag, -1);}int UUEXPORTUULoadFileWithPartNo (char *filename, char *fileid, int delflag, int partno){ int res, sr, count=0; struct stat finfo; fileread *loaded; uufile *fload; itbd *killem; FILE *datei; if ((datei = fopen (filename, "rb")) == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_SOURCE), filename, strerror (uu_errno = errno)); return UURET_IOERR; } if (fstat (fileno(datei), &finfo) == -1) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_STAT_FILE), filename, strerror (uu_errno = errno)); fclose (datei); return UURET_IOERR; } /* * schedule for destruction */ if (delflag && fileid==NULL) { if ((killem = (itbd *) malloc (sizeof (itbd))) == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_WARNING, uustring (S_OUT_OF_MEMORY), sizeof (itbd)); } else if ((killem->fname = _FP_strdup (filename)) == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_WARNING, uustring (S_OUT_OF_MEMORY), strlen(filename)+1); _FP_free (killem); } else { killem->NEXT = ftodel; ftodel = killem; } } progress.action = 0; progress.partno = 0; progress.numparts = 1; progress.fsize = (long) ((finfo.st_size>0)?finfo.st_size:-1); progress.percent = 0; progress.foffset = 0; _FP_strncpy (progress.curfile, (strlen(filename)>255)? (filename+strlen(filename)-255):filename, 256); progress.action = UUACT_SCANNING; if (fileid == NULL) fileid = filename; while (!feof (datei) && !ferror (datei)) { /* * Peek file, or some systems won't detect EOF */ res = fgetc (datei); if (feof (datei) || ferror (datei)) break; else ungetc (res, datei); if ((loaded = ScanPart (datei, fileid, &sr)) == NULL) { if (sr != UURET_NODATA && sr != UURET_OK && sr != UURET_CONT) { UUkillfread (loaded); if (sr != UURET_CANCEL) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_READ_ERROR), filename, strerror (uu_errno)); } UUCheckGlobalList (); progress.action = 0; fclose (datei); return sr; } continue; } if (ferror (datei)) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_READ_ERROR), filename, strerror (uu_errno = errno)); UUCheckGlobalList (); progress.action = 0; fclose (datei); return UURET_IOERR; } if (partno != -1) loaded->partno = partno; if ((loaded->uudet == QP_ENCODED || loaded->uudet == PT_ENCODED) && (loaded->filename == NULL || *(loaded->filename) == '\0') && !uu_handletext && (loaded->flags&FL_PARTIAL)==0) { /* * Don't want text */ UUkillfread (loaded); continue; } if ((loaded->subject == NULL || *(loaded->subject) == '\0') && (loaded->mimeid == NULL || *(loaded->mimeid) == '\0') && (loaded->filename== NULL || *(loaded->filename)== '\0') && (loaded->uudet == 0)) { /* * no useful data here */ UUkillfread (loaded); if (uu_fast_scanning && sr != UURET_CONT) break; continue; } if ((fload = UUPreProcessPart (loaded, &res)) == NULL) { /* * no useful data found */ if (res != UURET_NODATA) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_READ_ERROR), filename, (res==UURET_IOERR)?strerror(uu_errno):UUstrerror(res)); } UUkillfread (loaded); if (uu_fast_scanning && sr != UURET_CONT) break; continue; } if ((loaded->subject && *(loaded->subject)) || (loaded->mimeid && *(loaded->mimeid)) || (loaded->filename&& *(loaded->filename))|| (loaded->uudet)) { UUMessage (uulib_id, __LINE__, UUMSG_MESSAGE, uustring (S_LOADED_PART), filename, (loaded->subject) ? loaded->subject : "", (fload->subfname) ? fload->subfname : "", (loaded->filename) ? loaded->filename : "", fload->partno, (loaded->begin) ? "begin" : "", (loaded->end) ? "end" : "", codenames[loaded->uudet]); } if ((res = UUInsertPartToList (fload))) { /* * couldn't use the data */ UUkillfile (fload); if (res != UURET_NODATA) { UUCheckGlobalList (); progress.action = 0; fclose (datei); return res; } if (uu_fast_scanning && sr != UURET_CONT) break; continue; } /* * if in fast mode, we don't look any further, because we're told * that each source file holds at most one encoded part */ if (uu_fast_scanning && sr != UURET_CONT) break; if (loaded->uudet) count++; } if (ferror (datei)) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_READ_ERROR), filename, strerror (uu_errno = errno)); UUCheckGlobalList (); progress.action = 0; fclose (datei); return UURET_IOERR; } fclose (datei); if (!uu_fast_scanning && count==0) { UUMessage (uulib_id, __LINE__, UUMSG_NOTE, uustring (S_NO_DATA_FOUND), filename); } progress.action = 0; UUCheckGlobalList (); return UURET_OK;}/* * decode to a temporary file. this is well handled by uudecode() */int UUEXPORTUUDecodeToTemp (uulist *thefile){ return UUDecode (thefile);}/* * decode file first to temp file, then copy it to a final location */int UUEXPORTUUDecodeFile (uulist *thefile, char *destname){ FILE *target, *source; struct stat finfo; int fildes, res; size_t bytes; if (thefile == NULL) return UURET_ILLVAL; if ((res = UUDecode (thefile)) != UURET_OK) if (res != UURET_NOEND || !uu_desperate) return res; if (thefile->binfile == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NO_BIN_FILE)); return UURET_IOERR; } if ((source = fopen (thefile->binfile, "rb")) == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_FILE), thefile->binfile, strerror (uu_errno = errno)); return UURET_IOERR; } /* * for system security, strip setuid/setgid bits from mode */ if ((thefile->mode & 0777) != thefile->mode) { UUMessage (uulib_id, __LINE__, UUMSG_NOTE, uustring (S_STRIPPED_SETUID), destname, (int)thefile->mode); thefile->mode &= 0777; } /* * Determine the name of the target file according to the rules: * * IF (destname!=NULL) THEN filename=destname; * ELSE * filename = thefile->filename * IF (FilenameFilter!=NULL) THEN filename=FilenameFilter(filename); * filename = SaveFilePath + filename * END */ if (destname) strcpy (uugen_fnbuffer, destname); else { sprintf (uugen_fnbuffer, "%s%s", (uusavepath)?uusavepath:"", UUFNameFilter ((thefile->filename)? thefile->filename:"unknown.xxx")); } /* * if we don't want to overwrite existing files, check if it's there */ if (!uu_overwrite) { if (stat (uugen_fnbuffer, &finfo) == 0) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_TARGET_EXISTS), uugen_fnbuffer); fclose (source); return UURET_EXISTS; } } if (fstat (fileno(source), &finfo) == -1) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_STAT_FILE), thefile->binfile, strerror (uu_errno = errno)); fclose (source); return UURET_IOERR; } progress.action = 0; _FP_strncpy (progress.curfile, (strlen(uugen_fnbuffer)>255)? (uugen_fnbuffer+strlen(uugen_fnbuffer)-255):uugen_fnbuffer, 256); progress.partno = 0; progress.numparts = 1; progress.fsize = (long) ((finfo.st_size)?finfo.st_size:-1); progress.foffset = 0; progress.percent = 0; progress.action = UUACT_COPYING; if ((fildes = open (uugen_fnbuffer, O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, (uu_ignmode)?0666:thefile->mode)) == -1) { progress.action = 0; UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_TARGET), uugen_fnbuffer, strerror (uu_errno = errno)); fclose (source); return UURET_IOERR; } if ((target = fdopen (fildes, "wb")) == NULL) { progress.action = 0; UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_IO_ERR_TARGET), uugen_fnbuffer, strerror (uu_errno = errno)); fclose (source); close (fildes); return UURET_IOERR; } while (!feof (source)) { if (UUBUSYPOLL(ftell(source),progress.fsize)) { UUMessage (uulib_id, __LINE__, UUMSG_NOTE, uustring (S_DECODE_CANCEL)); fclose (source); fclose (target); unlink (uugen_fnbuffer); return UURET_CANCEL; } bytes = fread (uugen_inbuffer, 1, 1024, source); if (ferror (source) || (bytes == 0 && !feof (source))) { progress.action = 0; UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_READ_ERROR), thefile->binfile, strerror (uu_errno = errno)); fclose (source); fclose (target); unlink (uugen_fnbuffer); return UURET_IOERR; } if (fwrite (uugen_inbuffer, 1, bytes, target) != bytes) { progress.action = 0; UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_WR_ERR_TARGET), uugen_fnbuffer, strerror (uu_errno = errno)); fclose (source); fclose (target); unlink (uugen_fnbuffer); return UURET_IOERR; } } fclose (source); if (fclose (target)) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_WR_ERR_TARGET), uugen_fnbuffer, strerror (uu_errno = errno)); unlink (uugen_fnbuffer); return UURET_IOERR; } /* * after a successful decoding run, we delete the temporary file */ if (unlink (thefile->binfile)) { UUMessage (uulib_id, __LINE__, UUMSG_WARNING, uustring (S_TMP_NOT_REMOVED), thefile->binfile, strerror (uu_errno = errno)); } _FP_free (thefile->binfile); thefile->binfile = NULL; thefile->state &= ~UUFILE_TMPFILE; thefile->state |= UUFILE_DECODED; progress.action = 0; return UURET_OK;}/* * Calls a function repeatedly with all the info we have for a file * If the function returns non-zero, we break and don't send any more */int UUEXPORTUUInfoFile (uulist *thefile, void *opaque, int (*func) _ANSI_ARGS_((void *, char *))){ int errflag=0, res, bhflag=0, dd; long maxpos; FILE *inpfile; /* * We might need to ask our callback function to download the file */ if (uu_FileCallback) { if ((res = (*uu_FileCallback) (uu_FileCBArg, thefile->thisfile->data->sfname, uugen_fnbuffer, 1)) != UURET_OK) return res; if ((inpfile = fopen (uugen_fnbuffer, "rb")) == NULL) { (*uu_FileCallback) (uu_FileCBArg, thefile->thisfile->data->sfname, uugen_fnbuffer, 0); UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_FILE), uugen_fnbuffer, strerror (uu_errno = errno)); return UURET_IOERR; } } else { if ((inpfile = fopen (thefile->thisfile->data->sfname, "rb")) == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_FILE), thefile->thisfile->data->sfname, strerror (uu_errno=errno)); return UURET_IOERR; } _FP_strncpy (uugen_fnbuffer, thefile->thisfile->data->sfname, 1024); } /* * seek to beginning of info */ fseek (inpfile, thefile->thisfile->data->startpos, SEEK_SET); maxpos = thefile->thisfile->data->startpos + thefile->thisfile->data->length; while (!feof (inpfile) && (uu_fast_scanning || ftell(inpfile) < maxpos)) { if (_FP_fgets (uugen_inbuffer, 511, inpfile) == NULL) break; uugen_inbuffer[511] = '\0'; if (ferror (inpfile)) break; dd = UUValidData (uugen_inbuffer, 0, &bhflag); if (thefile->uudet == B64ENCODED && dd == B64ENCODED) break; else if (thefile->uudet == BH_ENCODED && bhflag) break; else if ((thefile->uudet == UU_ENCODED || thefile->uudet == XX_ENCODED) && strncmp (uugen_inbuffer, "begin ", 6) == 0) break; else if (thefile->uudet == YENC_ENCODED && strncmp (uugen_inbuffer, "=ybegin ", 8) == 0) break; if ((*func) (opaque, uugen_inbuffer)) break; } if (ferror (inpfile)) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_READ_ERROR), uugen_fnbuffer, strerror (uu_errno = errno)); errflag = 1; } fclose (inpfile); if (uu_FileCallback) (*uu_FileCallback) (uu_FileCBArg, thefile->thisfile->data->sfname, uugen_fnbuffer, 0); if (errflag) return UURET_IOERR; return UURET_OK;} int UUEXPORTUURenameFile (uulist *thefile, char *newname){ char *oldname; if (thefile == NULL) return UURET_ILLVAL; oldname = thefile->filename; if ((thefile->filename = _FP_strdup (newname)) == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_RENAME), oldname, newname); thefile->filename = oldname; return UURET_NOMEM; } _FP_free (oldname); return UURET_OK;}int UUEXPORTUURemoveTemp (uulist *thefile){ if (thefile == NULL) return UURET_ILLVAL; if (thefile->binfile) { if (unlink (thefile->binfile)) { UUMessage (uulib_id, __LINE__, UUMSG_WARNING, uustring (S_TMP_NOT_REMOVED), thefile->binfile, strerror (uu_errno = errno)); } _FP_free (thefile->binfile); thefile->binfile = NULL; thefile->state &= ~UUFILE_TMPFILE; } return UURET_OK;}int UUEXPORTUUCleanUp (void){ itbd *iter=ftodel, *ptr; uulist *liter; uufile *fiter; allomap *aiter; /* * delete temporary input files (such as the copy of stdin) */ while (iter) { if (unlink (iter->fname)) { UUMessage (uulib_id, __LINE__, UUMSG_WARNING, uustring (S_TMP_NOT_REMOVED), iter->fname, strerror (uu_errno = errno)); } _FP_free (iter->fname); ptr = iter; iter = iter->NEXT; _FP_free (ptr); } ftodel = NULL; /* * Delete input files after successful decoding */ if (uu_remove_input) { liter = UUGlobalFileList; while (liter) { if (liter->state & UUFILE_DECODED) { fiter = liter->thisfile; while (fiter) { if (fiter->data && fiter->data->sfname) { /* * Error code ignored. We might want to delete a file multiple * times */ unlink (fiter->data->sfname); } fiter = fiter->NEXT; } } liter = liter->NEXT; } } UUkilllist (UUGlobalFileList); UUGlobalFileList = NULL; _FP_free (uusavepath); _FP_free (uuencodeext); _FP_free (sstate.source); uusavepath = NULL; uuencodeext = NULL; UUkillheaders (&localenv); UUkillheaders (&sstate.envelope); memset (&localenv, 0, sizeof (headers)); memset (&sstate, 0, sizeof (scanstate)); while (mssdepth) { mssdepth--; UUkillheaders (&(multistack[mssdepth].envelope)); _FP_free (multistack[mssdepth].source); } /* * clean up the malloc'ed stuff */ for (aiter=toallocate; aiter->ptr; aiter++) { _FP_free (*(aiter->ptr)); *(aiter->ptr) = NULL; } return UURET_OK;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?