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