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; } }
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; }
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; }
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; }
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; }