Esempio n. 1
0
void
UUkilllist (uulist *data)
{
  uulist *next;

  while (data) {
    if (data->binfile != NULL)
      if (unlink (data->binfile))
	UUMessage (uuutil_id, __LINE__, UUMSG_WARNING,
		   uustring (S_TMP_NOT_REMOVED),
		   data->binfile, strerror (errno));

    _FP_free   (data->filename);
    _FP_free   (data->subfname);
    _FP_free   (data->mimeid);
    _FP_free   (data->mimetype);
    _FP_free   (data->binfile);
    UUkillfile (data->thisfile);
    _FP_free   (data->haveparts);
    _FP_free   (data->misparts);

    next = data->NEXT;
    _FP_free (data);
    data = next;
  }
}
Esempio n. 2
0
int UUEXPORT
UUSmerge (int pass)
{
  uulist *iter = UUGlobalFileList, *last=NULL, *res, *temp;
  int flag = 0;

  if (pass >= 0)
    {
      while (iter) {
        if ((iter->state & UUFILE_OK) || iter->uudet == 0) {
          last = iter;
          iter = iter->NEXT;
          continue;
        }
        if ((res = UU_smparts_r (iter, pass)) != NULL) {
          UUMessage (uuutil_id, __LINE__, UUMSG_MESSAGE,
		     uustring (S_SMERGE_MERGED),
		     (iter->subfname) ? iter->subfname : "",
		     (res->subfname)  ? res->subfname  : "", pass);
     
          temp       = iter->NEXT;
          iter->NEXT = NULL;
          UUkilllist (iter);

          flag++;

          if (last == NULL) {
	    UUGlobalFileList = temp;
	    iter             = temp;
          }
          else {
	    last->NEXT       = temp;
	    iter             = temp;
          }

          continue;
        }
        last = iter;
        iter = iter->NEXT;
      }
    }

  /*
   * check again
   */

  UUCheckGlobalList ();

  return flag;
}
Esempio n. 3
0
uufile *
UUPreProcessPart (fileread *data, int *ret)
{
  char *where, *whend, temp[80], *ptr, *p2;
  uufile *result;

  if ((result = (uufile *) malloc (sizeof (uufile))) == NULL) {
    UUMessage (uucheck_id, __LINE__, UUMSG_ERROR,
	       uustring (S_OUT_OF_MEMORY), sizeof (uufile));
    *ret = UURET_NOMEM;
    return NULL;
  }
  memset (result, 0, sizeof (uufile));

  if (data->partno) {
    where = whend  = NULL;
    result->partno = data->partno;
  }
  else if (uu_dumbness) {
    result->partno = -1;
    where = whend  = NULL;
  }
  else if ((result->partno=UUGetPartNo(data->subject,&where,&whend)) == -2) {
    *ret = UURET_NODATA;
    UUkillfile (result);
    return NULL;
  }

  if (data->filename != NULL) {
    if ((result->filename = _FP_strdup (data->filename)) == NULL) {
      UUMessage (uucheck_id, __LINE__, UUMSG_ERROR,
		 uustring (S_OUT_OF_MEMORY),
		 strlen (data->filename)+1);
      *ret = UURET_NOMEM;
      UUkillfile (result);
      return NULL;
    }
  }
  else
    result->filename = NULL;

  if (uu_dumbness <= 1)
    result->subfname = UUGetFileName (data->subject, where, whend);
  else
    result->subfname = NULL;

  result->mimeid   = _FP_strdup (data->mimeid);
  result->mimetype = _FP_strdup (data->mimetype);

  if (result->partno == -1 && 
      (data->uudet == PT_ENCODED || data->uudet == QP_ENCODED))
    result->partno = 1;

  if (data->flags & FL_SINGLE) {
    /*
     * Don't touch this part. But it should really have a filename
     */
    if (result->filename == NULL) {
      sprintf (temp, "%s.%03d", nofname, ++nofnum);
      result->filename = _FP_strdup (temp);
    }
    if (result->subfname == NULL)
      result->subfname = _FP_strdup (result->filename);

    if (result->filename == NULL || 
	result->subfname == NULL) {
      UUMessage (uucheck_id, __LINE__, UUMSG_ERROR,
		 uustring (S_OUT_OF_MEMORY),
		 (result->filename==NULL)?
		 (strlen(temp)+1):(strlen(result->filename)+1));
      *ret = UURET_NOMEM;
      UUkillfile(result);
      return NULL;
    }
    if (result->partno == -1)
      result->partno = 1;
  }
  else if (result->subfname == NULL && data->uudet &&
      (data->begin || result->partno == 1 || 
       (!uu_dumbness && result->partno == -1 && 
	(data->subject != NULL || result->filename != NULL)))) {
    /*
     * If it's the first part of something and has some valid data, but
     * no subject or anything, initialize lastvalid
     */
    /*
     * in this case, it really _should_ have a filename somewhere
     */
    if (result->filename != NULL)
      result->subfname = _FP_strdup (result->filename);
    else { /* if not, escape to UNKNOWN. We need to fill subfname */
      sprintf (temp, "%s.%03d", nofname, ++nofnum);
      result->subfname = _FP_strdup (temp);
    }
    /*
     * in case the strdup failed
     */
    if (result->subfname == NULL) {
      UUMessage (uucheck_id, __LINE__, UUMSG_ERROR,
		 uustring (S_OUT_OF_MEMORY),
		 (result->filename)?
		 (strlen(result->filename)+1):(strlen(temp)+1));
      *ret = UURET_NOMEM;
      UUkillfile (result);
      return NULL;
    }
    /*
     * if it's also got an 'end', or is the last part in a MIME-Mail,
     * then don't set lastvalid
     */
    if (!data->end && (!data->partno || data->partno != data->maxpno)) {
      /*
       * initialize lastvalid
       */
      lastvalid = 1;
      lastenc   = data->uudet;
      lastpart  = result->partno = 1;
      _FP_strncpy (uucheck_lastname, result->subfname, 256);
    }
    else
      result->partno = 1;
  }
  else if (result->subfname == NULL && data->uudet && data->mimeid) {
    /*
     * if it's got a file name, use it. Else use the mime-id for identifying
     * this part, and hope there's no other files encoded in the same message
     * under the same id.
     */
    if (result->filename)
      result->subfname = _FP_strdup (result->filename);
    else
      result->subfname = _FP_strdup (result->mimeid);
  }
  else if (result->subfname == NULL && data->uudet) {
    /*
     * ff we have lastvalid, use it. Make an exception for
     * Base64-encoded files.
     */
    if (data->uudet == B64ENCODED) {
      /*
       * Assume it's the first part. I wonder why it's got no part number?
       */
      if (result->filename != NULL)
        result->subfname = _FP_strdup (result->filename);
      else { /* if not, escape to UNKNOWN. We need to fill subfname */
        sprintf (temp, "%s.%03d", nofname, ++nofnum);
        result->subfname = _FP_strdup (temp);
      }
      if (result->subfname == NULL) {
	UUMessage (uucheck_id, __LINE__, UUMSG_ERROR,
		   uustring (S_OUT_OF_MEMORY),
		   (result->filename)?
		   (strlen(result->filename)+1):(strlen(temp)+1));
	*ret = UURET_NOMEM;
	UUkillfile (result);
        return NULL;
      }
      lastvalid = 0;
    }
    else if (lastvalid && data->uudet == lastenc && result->partno == -1) {
      result->subfname = _FP_strdup (uucheck_lastname);
      result->partno   = ++lastpart;

      /*
       * if it's the last part, invalidate lastvalid
       */
      if (data->end || (data->partno && data->partno == data->maxpno))
	lastvalid = 0;
    }
    else if (data->partno != -1 && result->filename) {
      result->subfname = _FP_strdup (result->filename);
    }
    else { 
      /* 
       * it's got no info, it's got no begin, and we don't know anything
       * about this part. Let's forget all about it.
       */
      *ret = UURET_NODATA;
      UUkillfile (result);
      return NULL;
    }
  }
  else if (result->subfname == NULL && result->partno == -1) {
    /*
     * This, too, is a part without any useful information that we
     * should forget about.
     */
    *ret = UURET_NODATA;
    UUkillfile (result);
    return NULL;
  }
  else if (result->subfname == NULL) {
    /*
     * This is a part without useful subject name, a valid part number
     * but no encoded data. It *could* be the zeroeth part of something,
     * but we don't care here. Just forget it.
     */
    *ret = UURET_NODATA;
    UUkillfile (result);
    return NULL;
  }

  /*
   * now, handle some cases where we have a useful subject but no
   * useful part number
   */

  if (result->partno == -1 && data->begin) {
    /*
     * hmm, this is reason enough to initialize lastvalid, at least 
     * if we have no end
     */
    if (!data->end) {
      _FP_strncpy (uucheck_lastname, result->subfname, 256);
      result->partno = lastpart = 1;
      lastenc = data->uudet;
      lastvalid = 1;
    }
    else
      result->partno = 1;
  }
  else if (result->partno == -1 && data->uudet) {
    if (lastvalid && _FP_stricmp (uucheck_lastname, result->subfname) == 0) {
      /*
       * if the subject filename is the same as last time, use part no
       * of lastvalid. If at end, invalidate lastvalid
       */
      result->partno = ++lastpart;

      if (data->end)
	lastvalid = 0;
    }
    else {
      /*
       * data but no part no. It's something UUInsertPartToList() should
       * handle
       */
      goto skipcheck;
    }
  }
  else if (result->partno == -1) {
    /*
     * it's got no data, so why should we need this one anyway?
     */
    *ret = UURET_NODATA;
    UUkillfile (result);
    return NULL;
  }

  /*
   * at this point, the part should have a valid subfname and a valid
   * part number. If it doesn't, then fail.
   */
  if (result->subfname == NULL || result->partno == -1) {
    *ret = UURET_NODATA;
    UUkillfile (result);
    return NULL;
  }

 skipcheck:

  if (result->filename) {
    if (*(ptr = _FP_cutdir (result->filename))) {
      p2 = _FP_strdup (ptr);
      _FP_free (result->filename);
      result->filename = p2;
    }
  }

  result->data = data;
  result->NEXT = NULL;

  *ret = UURET_OK;

  return result;
}
Esempio n. 4
0
static int 
UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc32_t *crc, crc32_t *pcrc)
{
  unsigned char *itemp = (unsigned char *) uuestr_itemp;
  unsigned char *otemp = (unsigned char *) uuestr_otemp;
  unsigned char *optr, *table, *tptr;
  int index, count;
  long line=0;
  size_t llen;

  if (outfile==NULL || infile==NULL ||
      (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
       encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) {
    UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
	       uustring (S_PARM_CHECK), "UUEncodeStream()");
    return UURET_ILLVAL;
  }

  /*
   * Special handling for plain text and quoted printable. Text is
   * read line oriented.
   */

  if (encoding == PT_ENCODED || encoding == QP_ENCODED) {
    while (!feof (infile) && (linperfile <= 0 || line < linperfile)) {
      if (_FP_fgets ((char*)itemp, 255, infile) == NULL) {
	break;
      }

      itemp[255] = '\0';
      count = strlen ((char*)itemp);

      llen = 0;
      optr = otemp;

      /*
       * Busy Callback
       */
      
      if (UUBUSYPOLL(ftell(infile)-progress.foffset,progress.fsize)) {
	UUMessage (uuencode_id, __LINE__, UUMSG_NOTE,
		   uustring (S_ENCODE_CANCEL));
	return UURET_CANCEL;
      }

      if (encoding == PT_ENCODED) {
	/*
	 * If there is a line feed, replace by eolstring
	 */
	if (count > 0 && itemp[count-1] == '\n') {
          const size_t n = strlen ((char*) eolstring);
	  itemp[--count] = '\0';
	  if (fwrite (itemp, 1, count, outfile) != count ||
	      fwrite ((char *) eolstring, 1, n, outfile) != n) {
	    return UURET_IOERR;
	  }
	}
	else {
	  if (fwrite (itemp, 1, count, outfile) != llen) {
	    return UURET_IOERR;
	  }
	}
      }
      else if (encoding == QP_ENCODED) {
	for (index=0; index<count; index++) {
	  if (llen == 0 && itemp[index] == '.') {
	    /*
	     * Special rule: encode '.' at the beginning of a line, so
	     * that some mailers aren't confused.
	     */
	    *optr++ = '=';
	    *optr++ = HexEncodeTable[itemp[index] >> 4];
	    *optr++ = HexEncodeTable[itemp[index] & 0x0f];
	    llen += 3;
	  }
	  else if ((itemp[index] >= 33 && itemp[index] <= 60) ||
		   (itemp[index] >= 62 && itemp[index] <= 126) ||
		   itemp[index] == 9 || itemp[index] == 32) {
	    *optr++ = itemp[index];
	    llen++;
	  }
	  else if (itemp[index] == '\n') {
	    /*
	     * If the last character before EOL was a space or tab,
	     * we must encode it. If llen > 74, there's no space to do
	     * that, so generate a soft line break instead.
	     */

	    if (index>0 && (itemp[index-1] == 9 || itemp[index-1] == 32)) {
	      *(optr-1) = '=';
	      if (llen <= 74) {
		*optr++ = HexEncodeTable[itemp[index-1] >> 4];
		*optr++ = HexEncodeTable[itemp[index-1] & 0x0f];
		llen += 2;
	      }
	    }

	    if (fwrite (otemp, 1, llen, outfile) != llen ||
		fwrite ((char *) eolstring, 1,
			strlen((char*)eolstring), outfile) != strlen ((char*)eolstring)) {
	      return UURET_IOERR;
	    }

	    /*
	     * Fix the soft line break condition from above
	     */

	    if (index>0 && (itemp[index-1] == 9 || itemp[index-1] == 32) &&
		*(optr-1) == '=') {
	      otemp[0] = '=';
	      otemp[1] = HexEncodeTable[itemp[index-1] >> 4];
	      otemp[2] = HexEncodeTable[itemp[index-1] & 0x0f];

	      if (fwrite (otemp, 1, 3, outfile) != 3 ||
		  fwrite ((char *) eolstring, 1,
			  strlen((char*)eolstring), outfile) != strlen ((char*)eolstring)) {
		return UURET_IOERR;
	      }
	    }

	    optr = otemp;
	    llen = 0;
	  }
Esempio n. 5
0
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;
}