#include "multipart.h" #include #include // Globals int isFilename(char *x) { char *y = rindex(x,'.'); char *z = index(x,'.'); return (y&&(y==z)&&(z!=x)); } int isPartInd(char *x) { if (index(x,'/')==NULL) return FALSE; if (strlen(x) < 5) return FALSE; if (strlen(index(x,'/')) < 3) return FALSE; char *y = x + strlen(x) - 1; if (((x[0]=='(')&&(y[0]==')'))||((x[0]=='[')&(y[0]==']'))) { char *q = x; while (*q != 0) { if (!(isdigit(*q) || (*q == '(') || (*q == ')') || (*q == '[') || (*q == ']') || (*q == '/'))) return FALSE; q++; } return TRUE; } else return FALSE; } int exists(char *filename) { FILE *f; f = fopen(filename,"r"); if (f) { fclose(f); return TRUE; } else return FALSE; } message::message(char *_subject) { subject = strdup(_subject); fileName = outfName = NULL; part = total = 0; do_processing(); } void message::findPartNumber() { char *x = strdup(subject); char *y = x; while ( y && (total == 0) && (*y != 0) ) { char *z; if (*y == '[') z = index(y, ']'); if (*y == '(') z = index(y, ')'); if (y && z) { char *w = index(y, '/'); if (w && (w < z)) { w = strdup(y); z = strtok(w, "/])"); part = atoi(z); z = strtok(NULL, "/])"); // Fix for missing "total" number if (z) total = atoi(z); else total = part = 0; if ( (total < part) || (!part) || (!total) ) { total = part = 0; } } } y++; char *t = index(y, '('); if (t) y = t; else y = index(y, '['); } free(x); } void message::do_processing() { char *x; char *y = strdup(subject); findPartNumber(); x = strtok(subject, " "); while (x) { if (isFilename(x)) fileName = strdup(x); else if (isPartInd(x)) { char *y = strtok(x+1, "/])"); part = atoi(y); y = strtok(NULL, "/])"); total = atoi(y); } x = strtok(NULL, " "); } checkForLongFilename(y); free(y); if (isMultiPart()) { outfName = (char *)malloc(strlen(fileName)+20); sprintf(outfName,"unfinished/%s.uue%d",fileName,part); } } void message::checkForLongFilename(char *subject) { // If there's a single dash with spaces around it occuring sometime // before the part number indicator in the subject, assume the // stuff between the dashes and the part number is a long filename char *x = strstr(subject, " - "); if (x) { // Skip the dashes and any leading spaces x+=3; while (x[0] == ' ') x++; // Look for the part number indicator char *y = strstr(x, " ("); if (!y) y = strstr(x, " ["); if (y) { while (y[0] == ' ') y--; y[1] = 0; while (strstr(x," - ")) { x = strstr(x," - "); x+=3; } // Filenames must contain a dot if (rindex(x, '.')) { fileName = strdup(x); } } } } int message::haveAllParts() { if (!isMultiPart()) return TRUE; int ret = TRUE; for (int i = 1; i <= total; i++) { char *tName = (char *)malloc(strlen(fileName)+20); sprintf(tName,"unfinished/%s.uue%d", fileName, i); if (!exists(tName)) ret = FALSE; free(tName); } return ret; } void message::joinParts() { FILE *outf; FILE *inf; char buf[1024]; int numRead; outf = fopen("outfile.txt","w"); for (int i = 1; i <= total; i++) { char *tName = (char *)malloc(strlen(fileName)+20); sprintf(tName,"unfinished/%s.uue%d", fileName, i); inf = fopen(tName,"r"); numRead = fread(buf, 1, 1024, inf); while (numRead > 0) { fwrite(buf, 1, numRead, outf); numRead = fread(buf, 1, 1024, inf); } fclose(inf); fflush(outf); unlink(tName); free(tName); } fclose(outf); }