00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 #ifdef _MSC_VER
00019 #include "config.h.win32"
00020 #else
00021 #include "config.h"
00022 #endif
00023 #endif
00024
00025 #ifdef SYSTEM_WINDLL
00026 #include
00027 #endif
00028 #ifdef SYSTEM_OS2
00029 #include
00030 #endif
00031
00032
00033
00034
00035
00036
00037
00038 #include
00039 #include
00040
00041 #ifdef STDC_HEADERS
00042 #include
00043 #include
00044 #endif
00045 #ifdef HAVE_MALLOC_H
00046 #include
00047 #endif
00048 #ifdef HAVE_UNISTD_H
00049 #include
00050 #endif
00051 #ifdef HAVE_MEMORY_H
00052 #include
00053 #endif
00054
00055 #include <uudeview.h>
00056 #include <uuint.h>
00057 #include <fptools.h>
00058 #include <uustring.h>
00059
00060 char * uucheck_id = "$Id: uucheck.c 2 2006-10-02 20:45:58Z csk $";
00061
00062
00063
00064
00065
00066
00067 #define MAXPLIST 256
00068
00069
00070
00071
00072
00073
00074 static char * UUGetFileName _ANSI_ARGS_((char *, char *, char *));
00075 static int UUGetPartNo _ANSI_ARGS_((char *, char **, char **));
00076
00077
00078
00079
00080
00081 int lastvalid, lastenc, nofnum;
00082 char *uucheck_lastname;
00083 char *uucheck_tempname;
00084 static int lastpart = 0;
00085 static char *nofname = "UNKNOWN";
00086
00087
00088
00089
00090
00091 static char *fnchars = "._-~!";
00092
00093
00094
00095
00096
00097
00098 static char *brackchr[] = {
00099 "()[]", "[]()"
00100 };
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 static char *
00111 UUGetFileName (char *subject, char *ptonum, char *ptonend)
00112 {
00113 char *ptr = subject, *iter, *result, *part;
00114 int count, length=0, alflag=0;
00115
00116
00117
00118
00119
00120
00121 if (subject == NULL)
00122 return NULL;
00123
00124
00125
00126
00127
00128
00129 if (uu_ignreply &&
00130 (subject[0] == 'R' || subject[0] == 'r') &&
00131 (subject[1] == 'E' || subject[1] == 'e') &&
00132 (subject[2] == ':' || subject[2] == ' ')) {
00133 return NULL;
00134 }
00135
00136
00137
00138
00139
00140
00141 if (_FP_strnicmp (subject, "repost", 6) == 0)
00142 subject += 6;
00143 if (_FP_strnicmp (subject, "re:", 3) == 0)
00144 subject += 3;
00145
00146 while (*subject == ' ' || *subject == ':') subject++;
00147
00148 part = _FP_stristr (subject, "part");
00149 if (part == subject) {
00150 subject += 4;
00151 while (*subject == ' ') subject++;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160 ptr = subject;
00161 while ((iter = strchr (ptr, '[')) != NULL) {
00162 if (strchr (iter, ']') == NULL) {
00163 ptr = iter + 1;
00164 continue;
00165 }
00166 iter++;
00167 while (isspace ((unsigned char)*iter))
00168 iter++;
00169 count = length = alflag = 0;
00170 while (iter[count] &&
00171 (isalnum ((unsigned char)iter[count]) || strchr (fnchars, iter[count])!=NULL)) {
00172 if (isalpha ((unsigned char)iter[count]))
00173 alflag++;
00174 count++;
00175 }
00176 if (count<4 || alflag==0) {
00177 ptr = iter + 1;
00178 continue;
00179 }
00180 length = count;
00181 while (isspace ((unsigned char)iter[count]))
00182 count++;
00183 if (iter[count] == ']') {
00184 ptr = iter;
00185 break;
00186 }
00187 length = 0;
00188 ptr = iter + 1;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198 if (length == 0) {
00199 ptr = subject;
00200 while ((iter = strchr (ptr, '/')) != NULL) {
00201 if (iter >= ptonum && iter <= ptonend) {
00202 ptr = iter + 1;
00203 continue;
00204 }
00205 count = length = 0;
00206 iter++;
00207 while (iter[count] &&
00208 (isalnum((unsigned char)iter[count])||strchr(fnchars, iter[count])!=NULL))
00209 count++;
00210 if (iter[count] == ' ' && length > 4) {
00211 length = count;
00212 break;
00213 }
00214 ptr = iter + ((count)?count:1);
00215 }
00216 }
00217
00218
00219
00220
00221
00222
00223 if (length == 0) {
00224 ptr = subject;
00225 while (*ptr && *ptr != 0x0a && *ptr != 0x0d && ptr != part) {
00226 iter = ptr;
00227 count = length = alflag = 0;
00228
00229 if (_FP_strnicmp (ptr, "ftp", 3) == 0) {
00230
00231 while (isalpha ((unsigned char)*ptr) || isdigit ((unsigned char)*ptr) || *ptr == '.')
00232 ptr++;
00233 continue;
00234 }
00235
00236 while ((isalnum((unsigned char)*iter)||strchr(fnchars, *iter)!=NULL||
00237 *iter=='/') && *iter && iter != ptonum && *iter != '.') {
00238 if (isalpha ((unsigned char)*iter))
00239 alflag = 1;
00240
00241 count++; iter++;
00242 }
00243 if (*iter == '\0' || iter == ptonum) {
00244 if (iter == ptonum)
00245 ptr = ptonend;
00246 else
00247 ptr = iter;
00248
00249 length = 0;
00250 continue;
00251 }
00252 if (*iter++ != '.' || count > 32 || alflag == 0) {
00253 ptr = iter;
00254 length = 0;
00255 continue;
00256 }
00257 if (_FP_strnicmp (iter, "edu", 3) == 0 ||
00258 _FP_strnicmp (iter, "gov", 3) == 0) {
00259
00260 while (isalpha ((unsigned char)*iter) || isdigit ((unsigned char)*iter) || *iter == '.')
00261 iter++;
00262 ptr = iter;
00263 length = 0;
00264 continue;
00265 }
00266
00267 length += count + 1;
00268 count = 0;
00269
00270 while ((isalnum((unsigned char)iter[count])||strchr(fnchars, iter[count])!=NULL||
00271 iter[count]=='/') && iter[count] && iter[count] != '.')
00272 count++;
00273
00274 if (iter[count]==':' && iter[count+1]=='/') {
00275
00276 ptr = iter + 1;
00277 length = 0;
00278 continue;
00279 }
00280
00281 if (count > 8 || iter == ptonum) {
00282 ptr = iter;
00283 length = 0;
00284 continue;
00285 }
00286
00287 if (iter[count] != '.') {
00288 length += count;
00289 break;
00290 }
00291
00292 while (iter[count] &&
00293 (isalnum((unsigned char)iter[count])||strchr(fnchars, iter[count])!=NULL||
00294 iter[count]=='/'))
00295 count++;
00296
00297 if (iter[count]==':' && iter[count+1]=='/') {
00298
00299 ptr = iter + 1;
00300 length = 0;
00301 continue;
00302 }
00303
00304 if (count < 12 && iter != ptonum) {
00305 length += count;
00306 break;
00307 }
00308
00309 ptr = iter;
00310 length = 0;
00311 }
00312 }
00313
00314 if (length == 0) {
00315 ptr = subject;
00316
00317 while (*ptr && !isalpha ((unsigned char)*ptr))
00318 ptr++;
00319
00320 while ((isalnum((unsigned char)ptr[length])||strchr(fnchars,ptr[length])!=NULL||
00321 ptr[length] == '/') &&
00322 ptr[length] && ptr+length!=part && ptr+length!=ptonum)
00323 length++;
00324
00325 if (length) {
00326 if (ptr[length] == '\0' || ptr[length] == 0x0a || ptr[length] == 0x0d) {
00327 length--;
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 }
00338 else {
00339 length--;
00340
00341 while (ptr[length] == ' ' && length > 0)
00342 length--;
00343 }
00344 length++;
00345 }
00346 }
00347
00348 if (length == 0) {
00349 ptr = nofname;
00350 length = strlen (nofname);
00351 }
00352
00353 if ((result = (char *) malloc (length + 1)) == NULL) {
00354 UUMessage (uucheck_id, __LINE__, UUMSG_ERROR,
00355 uustring (S_OUT_OF_MEMORY), length+1);
00356 return NULL;
00357 }
00358
00359 memcpy (result, ptr, length);
00360 result[length] = '\0';
00361
00362 return result;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 static int
00378 UUGetPartNo (char *subject, char **where, char **whend)
00379 {
00380 char *ptr = subject, *iter, *delim, bdel[2]=" ";
00381 int count, length=0, bpc;
00382
00383 *where = NULL; bdel[0] = ' ';
00384 *whend = NULL; bdel[1] = '\0';
00385
00386 iter = NULL;
00387 delim = "";
00388
00389 if (subject == NULL)
00390 return -1;
00391
00392 if (uu_ignreply &&
00393 (subject[0] == 'R' || subject[0] == 'r') &&
00394 (subject[1] == 'E' || subject[1] == 'e') &&
00395 (subject[2] == ':' || subject[2] == ' '))
00396 return -2;
00397
00398
00399
00400
00401
00402
00403 for (bpc=0, length=0; brackchr[uu_bracket_policy][bpc]; bpc+=2) {
00404 ptr = subject;
00405 while ((iter = strchr (ptr, brackchr[uu_bracket_policy][bpc])) != NULL) {
00406 count = length = 0; iter++;
00407
00408 while (*iter == ' ' || *iter == '#')
00409 iter++;
00410
00411 if (!isdigit ((unsigned char)*iter)) {
00412 ptr = iter;
00413 continue;
00414 }
00415 while (isdigit ((unsigned char)iter[count]))
00416 count++;
00417 length = count;
00418
00419 if (iter[count] == '\0' || iter[count+1] == '\0') {
00420 iter += count;
00421 length = 0;
00422 break;
00423 }
00424 if (iter[count] == brackchr[uu_bracket_policy][bpc+1]) {
00425 *where = iter;
00426 bdel[0] = brackchr[uu_bracket_policy][bpc+1];
00427 delim = bdel;
00428 break;
00429 }
00430
00431 while (iter[count] == ' ' || iter[count] == '#' ||
00432 iter[count] == '/' || iter[count] == '\\') count++;
00433
00434 if (_FP_strnicmp (iter + count, "of", 2) == 0)
00435 count += 2;
00436
00437 while (iter[count] == ' ') count++;
00438 while (isdigit ((unsigned char)iter[count])) count++;
00439 while (iter[count] == ' ') count++;
00440
00441 if (iter[count] == brackchr[uu_bracket_policy][bpc+1]) {
00442 *where = iter;
00443 bdel[0] = brackchr[uu_bracket_policy][bpc+1];
00444 delim = bdel;
00445 break;
00446 }
00447
00448 length = 0;
00449 ptr = iter;
00450 }
00451 if (length)
00452 break;
00453 }
00454
00455
00456
00457
00458
00459 if (length == 0) {
00460 if ((iter = _FP_stristr (subject, "part ")) != NULL) {
00461 iter += 5;
00462
00463 while (isspace ((unsigned char)*iter) || *iter == '.' || *iter == '-')
00464 iter++;
00465
00466 while (isdigit ((unsigned char)iter[length]))
00467 length++;
00468
00469 if (length == 0) {
00470 if (_FP_strnicmp (iter, "one", 3) == 0) length = 1;
00471 else if (_FP_strnicmp (iter, "two", 3) == 0) length = 2;
00472 else if (_FP_strnicmp (iter, "three", 5) == 0) length = 3;
00473 else if (_FP_strnicmp (iter, "four", 4) == 0) length = 4;
00474 else if (_FP_strnicmp (iter, "five", 4) == 0) length = 5;
00475 else if (_FP_strnicmp (iter, "six", 3) == 0) length = 6;
00476 else if (_FP_strnicmp (iter, "seven", 5) == 0) length = 7;
00477 else if (_FP_strnicmp (iter, "eight", 5) == 0) length = 8;
00478 else if (_FP_strnicmp (iter, "nine", 4) == 0) length = 9;
00479 else if (_FP_strnicmp (iter, "ten", 3) == 0) length = 10;
00480
00481 if (length && (*whend = strchr (iter, ' '))) {
00482 *where = iter;
00483 return length;
00484 }
00485 else
00486 length = 0;
00487 }
00488 else {
00489 *where = iter;
00490 delim = "of";
00491 }
00492 }
00493 }
00494
00495
00496
00497
00498
00499 if (length == 0) {
00500 if ((iter = _FP_stristr (subject, "part")) != NULL) {
00501 iter += 4;
00502
00503 while (isspace ((unsigned char)*iter) || *iter == '.' || *iter == '-')
00504 iter++;
00505
00506 while (isdigit ((unsigned char)iter[length]))
00507 length++;
00508
00509 if (length == 0) {
00510 if (_FP_strnicmp (iter, "one", 3) == 0) length = 1;
00511 else if (_FP_strnicmp (iter, "two", 3) == 0) length = 2;
00512 else if (_FP_strnicmp (iter, "three", 5) == 0) length = 3;
00513 else if (_FP_strnicmp (iter, "four", 4) == 0) length = 4;
00514 else if (_FP_strnicmp (iter, "five", 4) == 0) length = 5;
00515 else if (_FP_strnicmp (iter, "six", 3) == 0) length = 6;
00516 else if (_FP_strnicmp (iter, "seven", 5) == 0) length = 7;
00517 else if (_FP_strnicmp (iter, "eight", 5) == 0) length = 8;
00518 else if (_FP_strnicmp (iter, "nine", 4) == 0) length = 9;
00519 else if (_FP_strnicmp (iter, "ten", 3) == 0) length = 10;
00520
00521 if (length && (*whend = strchr (iter, ' '))) {
00522 *where = iter;
00523 return length;
00524 }
00525 else
00526 length = 0;
00527 }
00528 else {
00529 *where = iter;
00530 delim = "of";
00531 }
00532 }
00533 }
00534
00535
00536
00537
00538
00539 if (length == 0) {
00540 if ((iter = _FP_strirstr (subject, "of")) != NULL) {
00541 while (iter>subject && isspace ((unsigned char)*(iter-1)))
00542 iter--;
00543 if (isdigit((unsigned char)*(iter-1))) {
00544 while (iter>subject && isdigit ((unsigned char)*(iter-1)))
00545 iter--;
00546 if (!isdigit ((unsigned char)*iter) && !isalpha ((unsigned char)*iter) && *iter != '.')
00547 iter++;
00548 ptr = iter;
00549
00550 while (isdigit ((unsigned char)*ptr)) {
00551 ptr++; length++;
00552 }
00553 *where = iter;
00554 delim = "of";
00555 }
00556 }
00557 }
00558
00559
00560
00561
00562
00563 if (length == 0) {
00564 ptr = subject;
00565
00566 while (*ptr && length==0) {
00567 while (*ptr && !isdigit ((unsigned char)*ptr))
00568 ptr++;
00569 if (isdigit ((unsigned char)*ptr) && (ptr==subject || *ptr==' ' || *ptr=='/')) {
00570 while (isdigit ((unsigned char)ptr[length]))
00571 length++;
00572 if (ptr[length]!='\0' && ptr[length]!=' ' && ptr[length]!='/') {
00573 ptr += length;
00574 length = 0;
00575 }
00576 else {
00577 iter = ptr;
00578 bdel[0] = ptr[length];
00579 delim = bdel;
00580 }
00581 }
00582 else {
00583 while (isdigit ((unsigned char)*ptr))
00584 ptr++;
00585 }
00586 }
00587 }
00588
00589
00590
00591
00592
00593
00594 #if 0
00595 if (length == 0) {
00596 count = strlen(subject) - 1;
00597 ptr = subject;
00598
00599 while (count > 0) {
00600 if (!isdigit((unsigned char)ptr[count])||isalpha((unsigned char)ptr[count+1])||ptr[count+1] == '.') {
00601 count--;
00602 continue;
00603 }
00604 length = 0;
00605
00606 while (count >= 0 && isdigit ((unsigned char)ptr[count])) {
00607 count--; length++;
00608 }
00609 if (count>=0 && ((isalpha ((unsigned char)ptr[count]) &&
00610 (ptr[count] != 's' || ptr[count+1] != 't') &&
00611 (ptr[count] != 'n' || ptr[count+1] != 'd')) ||
00612 ptr[count] == '/' || ptr[count] == '.' ||
00613 ptr[count] == '-' || ptr[count] == '_')) {
00614 length = 0;
00615 continue;
00616 }
00617 count++;
00618 iter = ptr + count;
00619
00620 if (length > 4) {
00621 length = 0;
00622 continue;
00623 }
00624 *where = iter;
00625 delim = "of";
00626 break;
00627 }
00628 }
00629 #endif
00630
00631
00632
00633
00634
00635 if (length == 0) {
00636
00637
00638
00639 if ((iter = _FP_stristr (subject, "first")) != NULL) length = 1;
00640 else if ((iter = _FP_stristr (subject, "second")) != NULL) length = 2;
00641 else if ((iter = _FP_stristr (subject, "third")) != NULL) length = 3;
00642 else if ((iter = _FP_stristr (subject, "forth")) != NULL) length = 4;
00643 else if ((iter = _FP_stristr (subject, "fourth")) != NULL) length = 4;
00644 else if ((iter = _FP_stristr (subject, "fifth")) != NULL) length = 5;
00645 else if ((iter = _FP_stristr (subject, "sixth")) != NULL) length = 6;
00646 else if ((iter = _FP_stristr (subject, "seventh")) != NULL) length = 7;
00647 else if ((iter = _FP_stristr (subject, "eigth")) != NULL) length = 8;
00648 else if ((iter = _FP_stristr (subject, "nineth")) != NULL) length = 9;
00649 else if ((iter = _FP_stristr (subject, "ninth")) != NULL) length = 9;
00650 else if ((iter = _FP_stristr (subject, "tenth")) != NULL) length = 10;
00651 else iter = NULL;
00652
00653 if (length && iter && (*whend = strchr (iter, ' '))) {
00654 *where = iter;
00655 return length;
00656 }
00657 else
00658 length = 0;
00659 }
00660
00661 if (iter == NULL || length == 0)
00662 return -1;
00663
00664 *where = iter;
00665
00666 if (delim && delim[0]) {
00667 if ((*whend=_FP_stristr (iter, delim)) != NULL && (*whend - *where) < 12) {
00668 ptr = (*whend += strlen (delim));
00669
00670 while (*ptr == ' ')
00671 ptr++;
00672
00673 if (isdigit ((unsigned char)*ptr)) {
00674 *whend = ptr;
00675 while (isdigit ((unsigned char)**whend))
00676 *whend += 1;
00677 }
00678 }
00679 else {
00680 *whend = iter + length;
00681 }
00682 }
00683 else {
00684 *whend = iter + length;
00685 }
00686
00687 return atoi (iter);
00688 }
00689
00690
00691
00692
00693
00694 uufile *
00695 UUPreProcessPart (fileread *data, int *ret)
00696 {
00697 char *where, *whend, temp[80], *ptr, *p2;
00698 uufile *result;
00699
00700 if ((result = (uufile *) malloc (sizeof (uufile))) == NULL) {
00701 UUMessage (uucheck_id, __LINE__, UUMSG_ERROR,
00702 uustring (S_OUT_OF_MEMORY), sizeof (uufile));
00703 *ret = UURET_NOMEM;
00704 return NULL;
00705 }
00706 memset (result, 0, sizeof (uufile));
00707
00708 if (data->partno) {
00709 where = whend = NULL;
00710 result->partno = data->partno;
00711 }
00712 else if (uu_dumbness) {
00713 result->partno = -1;
00714 where = whend = NULL;
00715 }
00716 else if ((result->partno=UUGetPartNo(data->subject,&where,&whend)) == -2) {
00717 *ret = UURET_NODATA;
00718 UUkillfile (result);
00719 return NULL;
00720 }
00721
00722 if (data->filename != NULL) {
00723 if ((result->filename = _FP_strdup (data->filename)) == NULL) {
00724 UUMessage (uucheck_id, __LINE__, UUMSG_ERROR,
00725 uustring (S_OUT_OF_MEMORY),
00726 strlen (data->filename)+1);
00727 *ret = UURET_NOMEM;
00728 UUkillfile (result);
00729 return NULL;
00730 }
00731 }
00732 else
00733 result->filename = NULL;
00734
00735 if (uu_dumbness <= 1)
00736 result->subfname = UUGetFileName (data->subject, where, whend);
00737 else
00738 result->subfname = NULL;
00739
00740 result->mimeid = _FP_strdup (data->mimeid);
00741 result->mimetype = _FP_strdup (data->mimetype);
00742
00743 if (result->partno == -1 &&
00744 (data->uudet == PT_ENCODED || data->uudet == QP_ENCODED))
00745 result->partno = 1;
00746
00747 if (data->flags & FL_SINGLE) {
00748
00749
00750
00751 if (result->filename == NULL) {
00752 sprintf (temp, "%s.%03d", nofname, ++nofnum);
00753 result->filename = _FP_strdup (temp);
00754 }
00755 if (result->subfname == NULL)
00756 result->subfname = _FP_strdup (result->filename);
00757
00758 if (result->filename == NULL ||
00759 result->subfname == NULL) {
00760 UUMessage (uucheck_id, __LINE__, UUMSG_ERROR,
00761 uustring (S_OUT_OF_MEMORY),
00762 (result->filename==NULL)?
00763 (strlen(temp)+1):(strlen(result->filename)+1));
00764 *ret = UURET_NOMEM;
00765 UUkillfile(result);
00766 return NULL;
00767 }
00768 if (result->partno == -1)
00769 result->partno = 1;
00770 }
00771 else if (result->subfname == NULL && data->uudet &&
00772 (data->begin || result->partno == 1 ||
00773 (!uu_dumbness && result->partno == -1 &&
00774 (data->subject != NULL || result->filename != NULL)))) {
00775
00776
00777
00778
00779
00780
00781
00782 if (result->filename != NULL && *result->filename)
00783 result->subfname = _FP_strdup (result->filename);
00784 else {
00785 sprintf (temp, "%s.%03d", nofname, ++nofnum);
00786 result->subfname = _FP_strdup (temp);
00787 }
00788
00789
00790
00791 if (result->subfname == NULL) {
00792 UUMessage (uucheck_id, __LINE__, UUMSG_ERROR,
00793 uustring (S_OUT_OF_MEMORY),
00794 (result->filename)?
00795 (strlen(result->filename)+1):(strlen(temp)+1));
00796 *ret = UURET_NOMEM;
00797 UUkillfile (result);
00798 return NULL;
00799 }
00800
00801
00802
00803
00804 if (!data->end && (!data->partno || data->partno != data->maxpno)) {
00805
00806
00807
00808 lastvalid = 1;
00809 lastenc = data->uudet;
00810 lastpart = result->partno = 1;
00811 _FP_strncpy (uucheck_lastname, result->subfname, 256);
00812 }
00813 else
00814 result->partno = 1;
00815 }
00816 else if (result->subfname == NULL && data->uudet && data->mimeid) {
00817
00818
00819
00820
00821
00822 if (result->filename)
00823 result->subfname = _FP_strdup (result->filename);
00824 else
00825 result->subfname = _FP_strdup (result->mimeid);
00826 }
00827 else if (result->subfname == NULL && data->uudet) {
00828
00829
00830
00831
00832 if (data->uudet == B64ENCODED) {
00833
00834
00835
00836 if (result->filename != NULL && *result->filename)
00837 result->subfname = _FP_strdup (result->filename);
00838 else {
00839 sprintf (temp, "%s.%03d", nofname, ++nofnum);
00840 result->subfname = _FP_strdup (temp);
00841 }
00842 if (result->subfname == NULL) {
00843 UUMessage (uucheck_id, __LINE__, UUMSG_ERROR,
00844 uustring (S_OUT_OF_MEMORY),
00845 (result->filename)?
00846 (strlen(result->filename)+1):(strlen(temp)+1));
00847 *ret = UURET_NOMEM;
00848 UUkillfile (result);
00849 return NULL;
00850 }
00851 lastvalid = 0;
00852 }
00853 else if (lastvalid && data->uudet == lastenc && result->partno == -1) {
00854 result->subfname = _FP_strdup (uucheck_lastname);
00855 result->partno = ++lastpart;
00856
00857
00858
00859
00860 if (data->end || (data->partno && data->partno == data->maxpno))
00861 lastvalid = 0;
00862 }
00863 else if (data->partno != -1 && result->filename) {
00864 result->subfname = _FP_strdup (result->filename);
00865 }
00866 else {
00867
00868
00869
00870
00871 *ret = UURET_NODATA;
00872 UUkillfile (result);
00873 return NULL;
00874 }
00875 }
00876 else if (result->subfname == NULL && result->partno == -1) {
00877
00878
00879
00880
00881 *ret = UURET_NODATA;
00882 UUkillfile (result);
00883 return NULL;
00884 }
00885 else if (result->subfname == NULL) {
00886
00887
00888
00889
00890
00891 *ret = UURET_NODATA;
00892 UUkillfile (result);
00893 return NULL;
00894 }
00895
00896
00897
00898
00899
00900
00901 if (result->partno == -1 && data->begin) {
00902
00903
00904
00905
00906 if (!data->end) {
00907 _FP_strncpy (uucheck_lastname, result->subfname, 256);
00908 result->partno = lastpart = 1;
00909 lastenc = data->uudet;
00910 lastvalid = 1;
00911 }
00912 else
00913 result->partno = 1;
00914 }
00915 else if (result->partno == -1 && data->uudet) {
00916 if (lastvalid && _FP_stricmp (uucheck_lastname, result->subfname) == 0) {
00917
00918
00919
00920
00921 result->partno = ++lastpart;
00922
00923 if (data->end)
00924 lastvalid = 0;
00925 }
00926 else {
00927
00928
00929
00930
00931 goto skipcheck;
00932 }
00933 }
00934 else if (result->partno == -1) {
00935
00936
00937
00938 *ret = UURET_NODATA;
00939 UUkillfile (result);
00940 return NULL;
00941 }
00942
00943
00944
00945
00946
00947 if (result->subfname == NULL || result->partno == -1) {
00948 *ret = UURET_NODATA;
00949 UUkillfile (result);
00950 return NULL;
00951 }
00952
00953 skipcheck:
00954
00955 if (result->filename) {
00956 if (*(ptr = _FP_cutdir (result->filename))) {
00957 p2 = _FP_strdup (ptr);
00958 _FP_free (result->filename);
00959 result->filename = p2;
00960 }
00961 }
00962
00963 result->data = data;
00964 result->NEXT = NULL;
00965
00966 *ret = UURET_OK;
00967
00968 return result;
00969 }
00970
00971
00972
00973
00974
00975 int
00976 UUInsertPartToList (uufile *data)
00977 {
00978 uulist *iter = UUGlobalFileList, *unew;
00979 uufile *fiter, *last;
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997 while (iter) {
00998 if (data->data->flags & FL_SINGLE) {
00999
01000 }
01001 else if ((data->mimeid && iter->mimeid &&
01002 strcmp (data->mimeid, iter->mimeid) == 0) ||
01003 (_FP_stricmp (data->subfname, iter->subfname) == 0 &&
01004 !(iter->begin && data->data->begin) &&
01005 !(iter->end && data->data->end) &&
01006 !(data->mimeid && iter->mimeid &&
01007 strcmp (data->mimeid, iter->mimeid) != 0) &&
01008 !(data->filename && iter->filename &&
01009 strcmp (data->filename, iter->filename) != 0) &&
01010 !(iter->flags & FL_SINGLE))) {
01011
01012
01013
01014
01015
01016
01017
01018
01019 for (fiter=iter->thisfile; fiter; fiter=fiter->NEXT) {
01020 if (data->partno == fiter->partno)
01021 goto goahead;
01022 if (!iter->mimeid) {
01023 if (data->partno > fiter->partno && fiter->data->end) {
01024 goto goahead;
01025 }
01026 }
01027 }
01028
01029 if (iter->filename == NULL && data->filename != NULL) {
01030 if ((iter->filename = _FP_strdup (data->filename)) == NULL)
01031 return UURET_NOMEM;
01032 }
01033
01034
01035
01036
01037
01038
01039 if (data->data->uudet == B64ENCODED &&
01040 iter->uudet == XX_ENCODED && iter->begin) {
01041 data->data->uudet = XX_ENCODED;
01042 }
01043 else if (data->data->uudet == XX_ENCODED && data->data->begin &&
01044 iter->uudet == B64ENCODED) {
01045 iter->uudet = XX_ENCODED;
01046
01047 fiter = iter->thisfile;
01048 while (fiter) {
01049 fiter->data->uudet = XX_ENCODED;
01050 fiter = fiter->NEXT;
01051 }
01052 }
01053
01054
01055
01056
01057
01058 if (data->data->flags & FL_PARTIAL) {
01059 if (data->partno == 1) {
01060 iter->uudet = data->data->uudet;
01061 iter->flags = data->data->flags;
01062 }
01063 }
01064 else {
01065 if (data->data->uudet) iter->uudet = data->data->uudet;
01066 if (data->data->flags) iter->flags = data->data->flags;
01067 }
01068
01069 if (iter->mode == 0 && data->data->mode != 0)
01070 iter->mode = data->data->mode;
01071 if (data->data->begin) iter->begin = (data->partno)?data->partno:1;
01072 if (data->data->end) iter->end = (data->partno)?data->partno:1;
01073
01074 if (data->mimetype) {
01075 _FP_free (iter->mimetype);
01076 iter->mimetype = _FP_strdup (data->mimetype);
01077 }
01078
01079
01080
01081
01082
01083 if (data->partno != -1 && data->partno < iter->thisfile->partno) {
01084 iter->state = UUFILE_READ;
01085 data->NEXT = iter->thisfile;
01086 iter->thisfile = data;
01087 return UURET_OK;
01088 }
01089
01090
01091
01092
01093
01094 iter->state = UUFILE_READ;
01095 fiter = iter->thisfile;
01096 last = NULL;
01097
01098 while (fiter) {
01099
01100
01101
01102 if (data->partno == fiter->partno) {
01103 if (fiter->data->subject == NULL)
01104 return UURET_NODATA;
01105 else if (_FP_stristr (fiter->data->subject, "repost") != NULL &&
01106 _FP_stristr (data->data->subject, "repost") == NULL)
01107 return UURET_NODATA;
01108 else if (fiter->data->uudet && !data->data->uudet)
01109 return UURET_NODATA;
01110 else {
01111
01112
01113
01114 data->NEXT = fiter->NEXT;
01115 fiter->NEXT = NULL;
01116 UUkillfile (fiter);
01117
01118 if (last == NULL)
01119 iter->thisfile = data;
01120 else
01121 last->NEXT = data;
01122
01123 return UURET_OK;
01124 }
01125 }
01126
01127
01128
01129
01130
01131 if (fiter->NEXT == NULL ||
01132 (data->partno != -1 && data->partno < fiter->NEXT->partno)) {
01133 data->NEXT = fiter->NEXT;
01134 fiter->NEXT = data;
01135
01136 if (data->partno == -1)
01137 data->partno = fiter->partno + 1;
01138
01139 return UURET_OK;
01140 }
01141 last = fiter;
01142 fiter = fiter->NEXT;
01143 }
01144
01145 return UURET_OK;
01146 }
01147 goahead:
01148
01149
01150
01151 if (iter->NEXT == NULL)
01152 break;
01153
01154 iter = iter->NEXT;
01155 }
01156
01157
01158
01159
01160 if (data->partno == -1) {
01161
01162
01163
01164
01165
01166
01167 if (data->data->uudet == B64ENCODED || data->data->uudet == BH_ENCODED)
01168 data->partno = 1;
01169 else
01170 return UURET_NODATA;
01171 }
01172
01173 if ((unew = (uulist *) malloc (sizeof (uulist))) == NULL) {
01174 return UURET_NOMEM;
01175 }
01176
01177 if ((unew->subfname = _FP_strdup (data->subfname)) == NULL) {
01178 _FP_free (unew);
01179 return UURET_NOMEM;
01180 }
01181
01182 if (data->filename != NULL) {
01183 if ((unew->filename = _FP_strdup (data->filename)) == NULL) {
01184 _FP_free (unew->subfname);
01185 _FP_free (unew);
01186 return UURET_NOMEM;
01187 }
01188 }
01189 else
01190 unew->filename = NULL;
01191
01192 if (data->mimeid != NULL) {
01193 if ((unew->mimeid = _FP_strdup (data->mimeid)) == NULL) {
01194 _FP_free (unew->subfname);
01195 _FP_free (unew->filename);
01196 _FP_free (unew);
01197 return UURET_NOMEM;
01198 }
01199 }
01200 else
01201 unew->mimeid = NULL;
01202
01203 if (data->mimetype != NULL) {
01204 if ((unew->mimetype = _FP_strdup (data->mimetype)) == NULL) {
01205 _FP_free (unew->mimeid);
01206 _FP_free (unew->subfname);
01207 _FP_free (unew->filename);
01208 _FP_free (unew);
01209 return UURET_NOMEM;
01210 }
01211 }
01212 else
01213 unew->mimetype = NULL;
01214
01215 unew->state = UUFILE_READ;
01216 unew->binfile = NULL;
01217 unew->thisfile = data;
01218 unew->mode = data->data->mode;
01219 unew->uudet = data->data->uudet;
01220 unew->flags = data->data->flags;
01221 unew->begin = (data->data->begin) ? ((data->partno)?data->partno:1) : 0;
01222 unew->end = (data->data->end) ? ((data->partno)?data->partno:1) : 0;
01223 unew->misparts = NULL;
01224 unew->haveparts = NULL;
01225 unew->NEXT = NULL;
01226
01227 if (iter == NULL)
01228 UUGlobalFileList = unew;
01229 else
01230 iter->NEXT = unew;
01231
01232 return UURET_OK;
01233 }
01234
01235
01236
01237
01238
01239
01240 uulist *
01241 UUCheckGlobalList (void)
01242 {
01243 int misparts[MAXPLIST], haveparts[MAXPLIST];
01244 int miscount, havecount, count, flag, part;
01245 uulist *liter=UUGlobalFileList, *prev;
01246 uufile *fiter;
01247 long thesize;
01248
01249 while (liter) {
01250 miscount = 0;
01251 thesize = 0;
01252
01253 if (liter->state & UUFILE_OK) {
01254 liter = liter->NEXT;
01255 continue;
01256 }
01257 else if ((liter->uudet == QP_ENCODED ||
01258 liter->uudet == PT_ENCODED) &&
01259 (liter->flags & FL_SINGLE)) {
01260 if ((liter->flags&FL_PROPER)==0)
01261 liter->size = -1;
01262 else
01263 liter->size = liter->thisfile->data->length;
01264
01265 liter->state = UUFILE_OK;
01266 continue;
01267 }
01268 else if ((fiter = liter->thisfile) == NULL) {
01269 liter->state = UUFILE_NODATA;
01270 liter = liter->NEXT;
01271 continue;
01272 }
01273
01274
01275
01276
01277
01278 flag = 0;
01279 miscount = 0;
01280 havecount = 0;
01281 thesize = 0;
01282 liter->state = UUFILE_READ;
01283
01284
01285
01286
01287
01288 while (fiter && !fiter->data->uudet) {
01289 if (havecount<MAXPLIST) {
01290 haveparts[havecount++] = fiter->partno;
01291 }
01292 fiter = fiter->NEXT;
01293 }
01294
01295 if (fiter == NULL) {
01296 liter->state = UUFILE_NODATA;
01297 liter = liter->NEXT;
01298 continue;
01299 }
01300
01301 if (havecount<MAXPLIST) {
01302 haveparts[havecount++] = fiter->partno;
01303 }
01304
01305 if ((part = fiter->partno) > 1) {
01306 if (!fiter->data->begin) {
01307 for (count=1; count < part && miscount < MAXPLIST; count++) {
01308 misparts[miscount++] = count;
01309 }
01310 }
01311 }
01312
01313
01314
01315
01316
01317 if (miscount >= MAXPLIST) {
01318 liter->state = UUFILE_MISPART;
01319 liter = liter->NEXT;
01320 continue;
01321 }
01322
01323 if (liter->uudet == B64ENCODED ||
01324 liter->uudet == QP_ENCODED ||
01325 liter->uudet == PT_ENCODED)
01326 flag |= 3;
01327
01328 if (fiter->data->begin) flag |= 1;
01329 if (fiter->data->end) flag |= 2;
01330 if (fiter->data->uudet) flag |= 4;
01331
01332
01333
01334
01335
01336 switch (fiter->data->uudet) {
01337 case UU_ENCODED:
01338 case XX_ENCODED:
01339 thesize += 3*fiter->data->length/4;
01340 thesize -= 3*fiter->data->length/124;
01341 break;
01342 case B64ENCODED:
01343 thesize += 3*fiter->data->length/4;
01344 thesize -= fiter->data->length/52;
01345 break;
01346 case QP_ENCODED:
01347 case PT_ENCODED:
01348 thesize += fiter->data->length;
01349 break;
01350 }
01351
01352 fiter = fiter->NEXT;
01353
01354 while (fiter != NULL) {
01355 for (count=part+1; countpartno && miscount<MAXPLIST; count++)
01356 misparts[miscount++] = count;
01357
01358 part = fiter->partno;
01359
01360 if (havecount01361 haveparts[havecount++]=part;
01362
01363 if (fiter->data->begin) flag |= 1;
01364 if (fiter->data->end) flag |= 2;
01365 if (fiter->data->uudet) flag |= 4;
01366
01367 switch (fiter->data->uudet) {
01368 case UU_ENCODED:
01369 case XX_ENCODED:
01370 thesize += 3*fiter->data->length/4;
01371 thesize -= 3*fiter->data->length/124;
01372 break;
01373 case B64ENCODED:
01374 thesize += 3*fiter->data->length/4;
01375 thesize -= fiter->data->length/52;
01376 break;
01377 case QP_ENCODED:
01378 case PT_ENCODED:
01379 thesize += fiter->data->length;
01380 break;
01381 }
01382
01383 if (fiter->data->end)
01384 break;
01385
01386 fiter = fiter->NEXT;
01387 }
01388
01389
01390
01391
01392
01393
01394
01395 if (uu_fast_scanning && (flag & 0x01) && (flag & 0x04) &&
01396 (liter->uudet == UU_ENCODED || liter->uudet == XX_ENCODED))
01397 flag |= 2;
01398
01399
01400
01401
01402
01403 _FP_free (liter->haveparts);
01404 _FP_free (liter->misparts);
01405
01406 liter->haveparts = NULL;
01407 liter->misparts = NULL;
01408
01409 if (havecount) {
01410 if ((liter->haveparts=(int*)malloc((havecount+1)*sizeof(int)))!=NULL) {
01411 memcpy (liter->haveparts, haveparts, havecount*sizeof(int));
01412 liter->haveparts[havecount] = 0;
01413 }
01414 }
01415
01416 if (miscount) {
01417 if ((liter->misparts=(int*)malloc((miscount+1)*sizeof(int)))!=NULL) {
01418 memcpy (liter->misparts, misparts, miscount*sizeof(int));
01419 liter->misparts[miscount] = 0;
01420 }
01421 liter->state |= UUFILE_MISPART;
01422 }
01423
01424
01425
01426
01427
01428 if ((flag & 4) == 0) liter->state |= UUFILE_NODATA;
01429 if ((flag & 1) == 0) liter->state |= UUFILE_NOBEGIN;
01430 if ((flag & 2) == 0) liter->state |= UUFILE_NOEND;
01431
01432 if ((flag & 7) == 7 && miscount==0) {
01433 liter->state = UUFILE_OK;
01434 }
01435
01436 if ((uu_fast_scanning && (liter->flags&FL_PROPER)==0) || thesize<=0)
01437 liter->size = -1;
01438 else
01439 liter->size = thesize;
01440
01441 if (liter->state==UUFILE_OK &&
01442 (liter->filename==NULL || liter->filename[0]=='\0')) {
01443
01444
01445
01446 _FP_free (liter->filename);
01447 if (liter->subfname && liter->subfname[0] &&
01448 _FP_strpbrk (liter->subfname, "()[];: ") == NULL)
01449 liter->filename = _FP_strdup (liter->subfname);
01450 else {
01451 sprintf (uucheck_tempname, "%s.%03d", nofname, ++nofnum);
01452 liter->filename = _FP_strdup (uucheck_tempname);
01453 }
01454 }
01455 liter = liter->NEXT;
01456 }
01457
01458
01459
01460
01461
01462 liter = UUGlobalFileList;
01463 prev = NULL;
01464
01465 while (liter) {
01466 liter->PREV = prev;
01467 prev = liter;
01468 liter = liter->NEXT;
01469 }
01470
01471 return UUGlobalFileList;
01472 }
01473