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; } }
void UUkillheaders (headers *data) { if (data != NULL) { _FP_free (data->from); _FP_free (data->subject); _FP_free (data->rcpt); _FP_free (data->date); _FP_free (data->mimevers); _FP_free (data->ctype); _FP_free (data->ctenc); _FP_free (data->fname); _FP_free (data->boundary); _FP_free (data->mimeid); memset (data, 0, sizeof (headers)); } }
void UUkillfile (uufile *data) { uufile *next; while (data) { _FP_free (data->filename); _FP_free (data->subfname); _FP_free (data->mimeid); _FP_free (data->mimetype); UUkillfread (data->data); next = data->NEXT; _FP_free (data); data = next; } }
void UUkillfread (fileread *data) { if (data != NULL) { _FP_free (data->subject); _FP_free (data->filename); _FP_free (data->origin); _FP_free (data->mimeid); _FP_free (data->mimetype); _FP_free (data->sfname); _FP_free (data); } }
static int SendAFile (Tcl_Interp *interp, FILE *infile, char *infname, int encoding, int linperfile, char *outfname, char *towhom, char *subject, char *from, char *replyto, int isemail) { char *command, *rcptlist, *ptr; FILE *thepipe, *theifile; int len, count, res, part; if (towhom==NULL || (outfname==NULL&&infname==NULL) || (infile&&infname==NULL) || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) { Tcl_SetResult (interp, "oops: Parameter check failed in SendAFile()", TCL_STATIC); return UURET_ILLVAL; } #ifndef HAVE_POPEN Tcl_SetResult (interp, "error: Your system does not support sending of files", TCL_STATIC); return UURET_ILLVAL; #else if (isemail && (uue_mailprog == NULL || *uue_mailprog == '\0')) { Tcl_SetResult (interp, "error: Cannot Email file: option not configured", TCL_STATIC); return UURET_ILLVAL; } else if (!isemail && (uue_inewsprog == NULL || *uue_inewsprog == '\0')) { Tcl_SetResult (interp, "error: Cannot Post file: option not configured", TCL_STATIC); return UURET_ILLVAL; } len = strlen ((isemail)?uue_mailprog:uue_inewsprog) + ((uue_mpsubject)?strlen(subject):0) + ((isemail)?0:strlen(towhom)) + 32; if ((command = (char *) malloc (len)) == NULL) { Tcl_SetResult (interp, "error: Out of memory allocating some bytes", TCL_STATIC); return UURET_NOMEM; } if ((rcptlist = (char *) malloc (strlen (towhom) + 16)) == NULL) { Tcl_SetResult (interp, "error: Out of memory allocating some bytes", TCL_STATIC); _FP_free (command); return UURET_NOMEM; } if (isemail) { if (uue_mpsubject) sprintf (command, "%s -s \"%s\"", uue_mailprog, subject); else sprintf (command, "%s", uue_mailprog); /* * Attach list of recipients to mailer command and compose another list * of recipients */ count = 0; rcptlist[0] = '\0'; ptr = _FP_strtok (towhom, ",; "); while (ptr) { strcat (command, " "); strcat (command, ptr); if (count++) strcat (rcptlist, ","); strcat (rcptlist, ptr); ptr = _FP_strtok (NULL, ",; "); } } else { sprintf (command, "%s", uue_inewsprog); count = 0; rcptlist[0] = '\0'; ptr = _FP_strtok (towhom, ";, "); while (ptr) { if (count++) strcat (rcptlist, ","); strcat (rcptlist, ptr); ptr = _FP_strtok (NULL, ";, "); } } if (from && *from == '\0') { from = NULL; } if (subject && *subject == '\0') { subject = NULL; } if (replyto && *replyto == '\0') { replyto = NULL; } /* * Get going ... */ if (infile == NULL) { if ((theifile = fopen (infname, "rb")) == NULL) { _FP_free (rcptlist); _FP_free (command); return UURET_IOERR; } } else { theifile = infile; } for (part=1; !feof (theifile); part++) { if ((thepipe = popen (command, "w")) == NULL) { if (infile==NULL) fclose (theifile); _FP_free (rcptlist); _FP_free (command); return UURET_IOERR; } if (UUGetOption(UUOPT_VERBOSE, NULL, NULL, 0)) { #if 0 fprintf (stderr, "%s part %03d of %s to %s ... ", (isemail)?"mailing":"posting", part, (infname)?infname:outfname, rcptlist); fflush (stderr); #endif } res = UUE_PrepPartialExt (thepipe, theifile, infname, encoding, outfname, 0, part, linperfile, 0, rcptlist, from, subject, replyto, isemail); #if 0 if (UUGetOption (UUOPT_VERBOSE, NULL, NULL, 0)) { if (res == UURET_OK) fprintf (stderr, "ok.\n"); else fprintf (stderr, "%s\n", UUstrerror (res)); } #endif pclose (thepipe); if (res != UURET_OK) { if (infile == NULL) fclose (theifile); _FP_free (rcptlist); _FP_free (command); return res; } } if (infile == NULL) fclose (theifile); _FP_free (rcptlist); _FP_free (command); return UURET_OK; #endif }
int UUInsertPartToList (uufile *data) { uulist *iter = UUGlobalFileList, *unew; uufile *fiter, *last; /* * Part belongs together, if * (a) The file name received from the subject lines match _or_ * the MIME-IDs match, * (b) Not both parts have a begin line * (c) Not both parts have an end line * (d) Both parts don't have different MIME-IDs * (e) Both parts don't encode different files * (f) The other part wants to stay alone (FL_SINGLE) */ /* * check if this part wants to be left alone. If so, don't bother * to do all the checks */ while (iter) { if (data->data->flags & FL_SINGLE) { /* this space intentionally left blank */ } else if ((_FP_stricmp (data->subfname, iter->subfname) == 0 || (data->mimeid && iter->mimeid && strcmp (data->mimeid, iter->mimeid) == 0)) && !(iter->begin && data->data->begin) && !(iter->end && data->data->end) && !(data->mimeid && iter->mimeid && strcmp (data->mimeid, iter->mimeid) != 0) && !(data->filename && iter->filename && strcmp (data->filename, iter->filename) != 0) && !(iter->flags & FL_SINGLE)) { /* * if we already have this part, don't try to insert it */ for (fiter=iter->thisfile; fiter && (data->partno>fiter->partno) && !fiter->data->end; fiter=fiter->NEXT) /* empty loop */ ; if (fiter && (data->partno==fiter->partno || (data->partno > fiter->partno && fiter->data->end))) goto goahead; if (iter->filename == NULL && data->filename != NULL) { if ((iter->filename = _FP_strdup (data->filename)) == NULL) return UURET_NOMEM; } /* * special case when we might have tagged a part as Base64 when the * file was really XX */ if (data->data->uudet == B64ENCODED && iter->uudet == XX_ENCODED && iter->begin) { data->data->uudet = XX_ENCODED; } else if (data->data->uudet == XX_ENCODED && data->data->begin && iter->uudet == B64ENCODED) { iter->uudet = XX_ENCODED; fiter = iter->thisfile; while (fiter) { fiter->data->uudet = XX_ENCODED; fiter = fiter->NEXT; } } /* * If this is from a Message/Partial, we believe only the * iter->uudet from the first part */ if (data->data->flags & FL_PARTIAL) { if (data->partno == 1) { iter->uudet = data->data->uudet; iter->flags = data->data->flags; } } else { if (data->data->uudet) iter->uudet = data->data->uudet; if (data->data->flags) iter->flags = data->data->flags; } if (iter->mode == 0 && data->data->mode != 0) iter->mode = data->data->mode; if (data->data->begin) iter->begin = (data->partno)?data->partno:1; if (data->data->end) iter->end = (data->partno)?data->partno:1; if (data->mimetype) { _FP_free (iter->mimetype); iter->mimetype = _FP_strdup (data->mimetype); } /* * insert part at the beginning */ if (data->partno != -1 && data->partno < iter->thisfile->partno) { iter->state = UUFILE_READ; data->NEXT = iter->thisfile; iter->thisfile = data; return UURET_OK; } /* * insert part somewhere else */ iter->state = UUFILE_READ; /* prepare for re-checking */ fiter = iter->thisfile; last = NULL; while (fiter) { /* * if we find the same part no again, check which one looks better */ if (data->partno == fiter->partno) { if (fiter->data->subject == NULL) return UURET_NODATA; else if (_FP_stristr (fiter->data->subject, "repost") != NULL && _FP_stristr (data->data->subject, "repost") == NULL) return UURET_NODATA; else if (fiter->data->uudet && !data->data->uudet) return UURET_NODATA; else { /* * replace */ data->NEXT = fiter->NEXT; fiter->NEXT = NULL; UUkillfile (fiter); if (last == NULL) iter->thisfile = data; else last->NEXT = data; return UURET_OK; } } /* * if at the end of the part list, add it */ if (fiter->NEXT == NULL || (data->partno != -1 && data->partno < fiter->NEXT->partno)) { data->NEXT = fiter->NEXT; fiter->NEXT = data; if (data->partno == -1) data->partno = fiter->partno + 1; return UURET_OK; } last = fiter; fiter = fiter->NEXT; } return UURET_OK; /* Shouldn't get here */ } goahead: /* * we need iter below */ if (iter->NEXT == NULL) break; iter = iter->NEXT; } /* * handle new entry */ if (data->partno == -1) { /* * if it's got no part no, and it's MIME mail, then assume this is * part no. 1. If it's not MIME, then we can't handle it; if it * had a 'begin', it'd have got a part number assigned by * UUPreProcessPart(). */ if (data->data->uudet == B64ENCODED || data->data->uudet == BH_ENCODED) data->partno = 1; else return UURET_NODATA; } if ((unew = (uulist *) malloc (sizeof (uulist))) == NULL) { return UURET_NOMEM; } if ((unew->subfname = _FP_strdup (data->subfname)) == NULL) { _FP_free (unew); return UURET_NOMEM; } if (data->filename != NULL) { if ((unew->filename = _FP_strdup (data->filename)) == NULL) { _FP_free (unew->subfname); _FP_free (unew); return UURET_NOMEM; } } else unew->filename = NULL; if (data->mimeid != NULL) { if ((unew->mimeid = _FP_strdup (data->mimeid)) == NULL) { _FP_free (unew->subfname); _FP_free (unew->filename); _FP_free (unew); return UURET_NOMEM; } } else unew->mimeid = NULL; if (data->mimetype != NULL) { if ((unew->mimetype = _FP_strdup (data->mimetype)) == NULL) { _FP_free (unew->mimeid); _FP_free (unew->subfname); _FP_free (unew->filename); _FP_free (unew); return UURET_NOMEM; } } else unew->mimetype = NULL; unew->state = UUFILE_READ; unew->binfile = NULL; unew->thisfile = data; unew->mode = data->data->mode; unew->uudet = data->data->uudet; unew->flags = data->data->flags; unew->begin = (data->data->begin) ? ((data->partno)?data->partno:1) : 0; unew->end = (data->data->end) ? ((data->partno)?data->partno:1) : 0; unew->misparts = NULL; unew->haveparts = NULL; unew->NEXT = NULL; if (iter == NULL) UUGlobalFileList = unew; else iter->NEXT = unew; return UURET_OK; }
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; }
uulist * UUCheckGlobalList (void) { int misparts[MAXPLIST], haveparts[MAXPLIST]; int miscount, havecount, count, flag, part; uulist *liter=UUGlobalFileList, *prev; uufile *fiter; long thesize; while (liter) { miscount = 0; thesize = 0; if (liter->state & UUFILE_OK) { liter = liter->NEXT; continue; } else if ((liter->uudet == QP_ENCODED || liter->uudet == PT_ENCODED) && (liter->flags & FL_SINGLE)) { if ((liter->flags&FL_PROPER)==0) liter->size = -1; else liter->size = liter->thisfile->data->length; liter->state = UUFILE_OK; continue; } else if ((fiter = liter->thisfile) == NULL) { liter->state = UUFILE_NODATA; liter = liter->NEXT; continue; } /* * Re-Check this file */ flag = 0; miscount = 0; havecount = 0; thesize = 0; liter->state = UUFILE_READ; /* * search encoded data */ while (fiter && !fiter->data->uudet) { if (havecount<MAXPLIST) { haveparts[havecount++] = fiter->partno; } fiter = fiter->NEXT; } if (fiter == NULL) { liter->state = UUFILE_NODATA; liter = liter->NEXT; continue; } if (havecount<MAXPLIST) { haveparts[havecount++] = fiter->partno; } if ((part = fiter->partno) > 1) { if (!fiter->data->begin) { for (count=1; count < part && miscount < MAXPLIST; count++) misparts[miscount++] = count; } } /* * don't care if so many parts are missing */ if (miscount >= MAXPLIST) { liter->state = UUFILE_MISPART; liter = liter->NEXT; continue; } if (liter->uudet == B64ENCODED || liter->uudet == QP_ENCODED || liter->uudet == PT_ENCODED) flag |= 3; /* Don't need begin or end with Base64 or plain text*/ if (fiter->data->begin) flag |= 1; if (fiter->data->end) flag |= 2; if (fiter->data->uudet) flag |= 4; /* * guess size of part */ switch (fiter->data->uudet) { case UU_ENCODED: case XX_ENCODED: thesize += 3*fiter->data->length/4; thesize -= 3*fiter->data->length/124; /* substract 2 of 62 chars */ break; case B64ENCODED: thesize += 3*fiter->data->length/4; thesize -= fiter->data->length/52; /* substract 2 of 78 chars */ break; case QP_ENCODED: case PT_ENCODED: thesize += fiter->data->length; break; } fiter = fiter->NEXT; while (fiter != NULL) { for (count=part+1; count<fiter->partno && miscount<MAXPLIST; count++) misparts[miscount++] = count; part = fiter->partno; if (havecount<MAXPLIST) haveparts[havecount++]=part; if (fiter->data->begin) flag |= 1; if (fiter->data->end) flag |= 2; if (fiter->data->uudet) flag |= 4; switch (fiter->data->uudet) { case UU_ENCODED: case XX_ENCODED: thesize += 3*fiter->data->length/4; thesize -= 3*fiter->data->length/124; /* substract 2 of 62 chars */ break; case B64ENCODED: thesize += 3*fiter->data->length/4; thesize -= fiter->data->length/52; /* substract 2 of 78 chars */ break; case QP_ENCODED: case PT_ENCODED: thesize += fiter->data->length; break; } if (fiter->data->end) break; fiter = fiter->NEXT; } /* * if in fast mode, we don't notice an 'end'. So if its uu or xx * encoded, there's a begin line and encoded data, assume it's * there. */ if (uu_fast_scanning && (flag & 0x01) && (flag & 0x04) && (liter->uudet == UU_ENCODED || liter->uudet == XX_ENCODED)) flag |= 2; /* * Set the parts we have and/or missing */ _FP_free (liter->haveparts); _FP_free (liter->misparts); liter->haveparts = NULL; liter->misparts = NULL; if (havecount) { if ((liter->haveparts=(int*)malloc((havecount+1)*sizeof(int)))!=NULL) { memcpy (liter->haveparts, haveparts, havecount*sizeof(int)); liter->haveparts[havecount] = 0; } } if (miscount) { if ((liter->misparts=(int*)malloc((miscount+1)*sizeof(int)))!=NULL) { memcpy (liter->misparts, misparts, miscount*sizeof(int)); liter->misparts[miscount] = 0; } liter->state |= UUFILE_MISPART; } /* * Finalize checking */ if ((flag & 4) == 0) liter->state |= UUFILE_NODATA; if ((flag & 1) == 0) liter->state |= UUFILE_NOBEGIN; if ((flag & 2) == 0) liter->state |= UUFILE_NOEND; if ((flag & 7) == 7 && miscount==0) { liter->state = UUFILE_OK; } if ((uu_fast_scanning && (liter->flags&FL_PROPER)==0) || thesize<=0) liter->size = -1; else liter->size = thesize; if (liter->state==UUFILE_OK && (liter->filename==NULL || liter->filename[0]=='\0')) { /* * Emergency backup if the file does not have a filename */ _FP_free (liter->filename); if (liter->subfname && liter->subfname[0] && _FP_strpbrk (liter->subfname, "()[];: ") == NULL) liter->filename = _FP_strdup (liter->subfname); else { sprintf (uucheck_tempname, "%s.%03d", nofname, ++nofnum); liter->filename = _FP_strdup (uucheck_tempname); } } liter = liter->NEXT; } /* * Sets back (PREV) links */ liter = UUGlobalFileList; prev = NULL; while (liter) { liter->PREV = prev; prev = liter; liter = liter->NEXT; } return UUGlobalFileList; }