00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef HAVE_CONFIG_H
00023 #ifdef _MSC_VER
00024 #include "config.h.win32"
00025 #else
00026 #include "config.h"
00027 #endif
00028 #endif
00029
00030 #ifdef SYSTEM_WINDLL
00031 #include
00032 #endif
00033 #ifdef SYSTEM_OS2
00034 #include
00035 #endif
00036
00037 #include
00038 #include
00039 #include
00040
00041 #ifdef HAVE_FCNTL_H
00042 #include
00043 #endif
00044
00045 #ifdef STDC_HEADERS
00046 #include
00047 #include
00048 #include
00049 #else
00050 #ifdef HAVE_STDARG_H
00051 #include
00052 #else
00053 #ifdef HAVE_VARARGS_H
00054 #include
00055 #endif
00056 #endif
00057 #endif
00058
00059 #ifdef HAVE_UNISTD_H
00060 #include
00061 #endif
00062
00063 #ifdef TIME_WITH_SYS_TIME
00064 # include
00065 # include
00066 #else
00067 # ifdef HAVE_SYS_TIME_H
00068 # include
00069 # else
00070 # include
00071 # endif
00072 #endif
00073
00074 #ifdef HAVE_ERRNO_H
00075 #include
00076 #endif
00077
00078
00079 #ifdef HAVE_IO_H
00080 #include
00081 #endif
00082
00083 #ifdef _MSC_VER
00084 #include
00085 #endif
00086
00087 #include uudeview.h>
00088 #include uuint.h>
00089 #include fptools.h>
00090 #include uustring.h>
00091
00092 char * uulib_id = "$Id: uulib.c 260 2007-05-04 23:32:54Z csk $";
00093
00094 #ifdef SYSTEM_WINDLL
00095 BOOL _export WINAPI
00096 DllEntryPoint (HINSTANCE hInstance, DWORD seginfo,
00097 LPVOID lpCmdLine)
00098 {
00099
00100 return TRUE;
00101 }
00102 #endif
00103
00104
00105
00106
00107
00108 #ifndef O_BINARY
00109 #define O_BINARY 0
00110 #endif
00111
00112
00113 #ifndef SEEK_SET
00114 #ifdef L_BEGIN
00115 #define SEEK_SET L_BEGIN
00116 #else
00117 #define SEEK_SET 0
00118 #endif
00119 #endif
00120
00121
00122
00123
00124
00125 void (*uu_MsgCallback) _ANSI_ARGS_((void *, char *, int)) = NULL;
00126 int (*uu_BusyCallback) _ANSI_ARGS_((void *, uuprogress *)) = NULL;
00127 int (*uu_FileCallback) _ANSI_ARGS_((void *, char *, char *, int)) = NULL;
00128 char * (*uu_FNameFilter) _ANSI_ARGS_((void *, char *)) = NULL;
00129
00130 void *uu_MsgCBArg = NULL;
00131 void *uu_BusyCBArg = NULL;
00132 void *uu_FileCBArg = NULL;
00133 void *uu_FFCBArg = NULL;
00134
00135
00136
00137
00138
00139 int uu_fast_scanning = 0;
00140 int uu_bracket_policy = 0;
00141 int uu_verbose = 1;
00142 int uu_desperate = 0;
00143 int uu_ignreply = 0;
00144 int uu_debug = 0;
00145 int uu_errno = 0;
00146 int uu_dumbness = 0;
00147 int uu_overwrite = 1;
00148 int uu_ignmode = 0;
00149 int uu_handletext = 0;
00150 int uu_usepreamble = 0;
00151 int uu_tinyb64 = 0;
00152 int uu_remove_input = 0;
00153 int uu_more_mime = 0;
00154
00155 headercount hlcount = {
00156 3,
00157 2,
00158 1
00159 };
00160
00161
00162
00163
00164
00165 char uulibversion[256] = "0.5pl20";
00166
00167
00168
00169
00170
00171 char *uusavepath;
00172
00173
00174
00175
00176
00177 char *uuencodeext;
00178
00179
00180
00181
00182
00183 char *uulib_msgstring;
00184 char *uugen_inbuffer;
00185 char *uugen_fnbuffer;
00186
00187
00188
00189
00190
00191 uulist *UUGlobalFileList = NULL;
00192
00193
00194
00195
00196
00197 static long uu_busy_msecs = 0;
00198 static long uu_last_secs = 0;
00199 static long uu_last_usecs = 0;
00200
00201
00202
00203
00204
00205 uuprogress progress;
00206
00207
00208
00209
00210
00211 typedef struct _itbd {
00212 char *fname;
00213 struct _itbd *NEXT;
00214 } itbd;
00215 static itbd * ftodel = NULL;
00216
00217
00218
00219
00220
00221 unsigned long uuyctr;
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 typedef struct {
00232 char **ptr;
00233 size_t size;
00234 } allomap;
00235
00236 static allomap toallocate[] = {
00237 { &uugen_fnbuffer, UUGEN_FNBUFFER_LEN },
00238 { &uugen_inbuffer, 1024 },
00239 { &uucheck_lastname, 256 },
00240 { &uucheck_tempname, 256 },
00241 { &uuestr_itemp, 256 },
00242 { &uuestr_otemp, 1024 },
00243 { &uulib_msgstring, 1024 },
00244 { &uuncdl_fulline, 300 },
00245 { &uuncdp_oline, 1200 },
00246 { &uunconc_UUxlat, 256 * sizeof (int) },
00247 { &uunconc_UUxlen, 64 * sizeof (int) },
00248 { &uunconc_B64xlat, 256 * sizeof (int) },
00249 { &uunconc_XXxlat, 256 * sizeof (int) },
00250 { &uunconc_BHxlat, 256 * sizeof (int) },
00251 { &uunconc_save, 3*300 },
00252 { &uuscan_shlline, 1024 },
00253 { &uuscan_shlline2, 1024 },
00254 { &uuscan_pvvalue, 4096 },
00255 { &uuscan_phtext, 4096 },
00256 { &uuscan_sdline, UUSCAN_SDLINE_LEN },
00257 { &uuscan_sdbhds1, 300 },
00258 { &uuscan_sdbhds2, 300 },
00259 { &uuscan_spline, UUSCAN_SPLINE_LEN },
00260 { &uuutil_bhwtmp, 300 },
00261 { NULL, 0 }
00262 };
00263
00264
00265
00266
00267
00268 #if defined(STDC_HEADERS) || defined(HAVE_STDARG_H)
00269 int
00270 UUMessage (char *file, int line, int level, char *format, ...)
00271 #else
00272 int
00273 UUMessage (va_alist)
00274 va_dcl
00275 #endif
00276 {
00277 char *msgptr;
00278 #if defined(STDC_HEADERS) || defined(HAVE_STDARG_H)
00279 va_list ap;
00280
00281 va_start (ap, format);
00282 #else
00283 char *file, *format;
00284 int line, level;
00285 va_list ap;
00286
00287 va_start (ap);
00288 file = va_arg (ap, char *);
00289 line = va_arg (ap, int);
00290 level = va_arg (ap, int);
00291 format = va_arg (ap, char *);
00292 #endif
00293
00294 if (uu_debug) {
00295 sprintf (uulib_msgstring, "%s(%d): %s", file, line, msgnames[level]);
00296 msgptr = uulib_msgstring + strlen (uulib_msgstring);
00297 }
00298 else {
00299 sprintf (uulib_msgstring, "%s", msgnames[level]);
00300 msgptr = uulib_msgstring + strlen (uulib_msgstring);
00301 }
00302
00303 if (uu_MsgCallback && (level>UUMSG_NOTE || uu_verbose)) {
00304 vsprintf (msgptr, format, ap);
00305
00306 (*uu_MsgCallback) (uu_MsgCBArg, uulib_msgstring, level);
00307 }
00308
00309 va_end (ap);
00310
00311 return UURET_OK;
00312 }
00313
00314
00315
00316
00317
00318
00319 int
00320 UUBusyPoll (void)
00321 {
00322 #ifdef HAVE_GETTIMEOFDAY
00323 struct timeval tv;
00324 long msecs;
00325
00326 if (uu_BusyCallback) {
00327 (void) gettimeofday (&tv, NULL);
00328
00329 msecs = 1000*(tv.tv_sec-uu_last_secs)+(tv.tv_usec-uu_last_usecs)/1000;
00330
00331 if (uu_last_secs==0 || msecs > uu_busy_msecs) {
00332 uu_last_secs = tv.tv_sec;
00333 uu_last_usecs = tv.tv_usec;
00334
00335 return (*uu_BusyCallback) (uu_BusyCBArg, &progress);
00336 }
00337 }
00338 #else
00339 time_t now = time (NULL);
00340 long msecs;
00341
00342 if (uu_BusyCallback) {
00343 if (uu_busy_msecs 00344 msecs = 1;
00345 }
00346 else {
00347 msecs = 1000 * (now - uu_last_secs);
00348 }
00349
00350 if (uu_last_secs==0 || msecs > uu_busy_msecs) {
00351 uu_last_secs = now;
00352 uu_last_usecs = 0;
00353
00354 return (*uu_BusyCallback) (uu_BusyCBArg, &progress);
00355 }
00356 }
00357 #endif
00358
00359 return 0;
00360 }
00361
00362
00363
00364
00365
00366 int UUEXPORT
00367 UUInitialize (void)
00368 {
00369 allomap *aiter;
00370
00371 progress.action = 0;
00372 progress.curfile[0] = '\0';
00373
00374 ftodel = NULL;
00375
00376 uusavepath = NULL;
00377 uuencodeext = NULL;
00378
00379 mssdepth = 0;
00380 memset (&localenv, 0, sizeof (headers));
00381 memset (&sstate, 0, sizeof (scanstate));
00382
00383 nofnum = 0;
00384 mimseqno = 0;
00385 lastvalid = 0;
00386 lastenc = 0;
00387 uuyctr = 0;
00388
00389
00390
00391
00392
00393 for (aiter=toallocate; aiter->ptr; aiter++)
00394 *(aiter->ptr) = NULL;
00395
00396 for (aiter=toallocate; aiter->ptr; aiter++) {
00397 if ((*(aiter->ptr) = (char *) malloc (aiter->size)) == NULL) {
00398
00399
00400
00401
00402 for (aiter=toallocate; aiter->ptr; aiter++) {
00403 _FP_free (*(aiter->ptr));
00404 }
00405 return UURET_NOMEM;
00406 }
00407 }
00408
00409
00410
00411
00412
00413 UUInitConc ();
00414
00415 return UURET_OK;
00416 }
00417
00418
00419
00420
00421
00422 int UUEXPORT
00423 UUGetOption (int option, int *ivalue, char *cvalue, int clength)
00424 {
00425 int result;
00426
00427 switch (option) {
00428 case UUOPT_VERSION:
00429 _FP_strncpy (cvalue, uulibversion, clength);
00430 result = 0;
00431 break;
00432 case UUOPT_FAST:
00433 if (ivalue) *ivalue = uu_fast_scanning;
00434 result = uu_fast_scanning;
00435 break;
00436 case UUOPT_DUMBNESS:
00437 if (ivalue) *ivalue = uu_dumbness;
00438 result = uu_dumbness;
00439 break;
00440 case UUOPT_BRACKPOL:
00441 if (ivalue) *ivalue = uu_bracket_policy;
00442 result = uu_bracket_policy;
00443 break;
00444 case UUOPT_VERBOSE:
00445 if (ivalue) *ivalue = uu_verbose;
00446 result = uu_verbose;
00447 break;
00448 case UUOPT_DESPERATE:
00449 if (ivalue) *ivalue = uu_desperate;
00450 result = uu_desperate;
00451 break;
00452 case UUOPT_IGNREPLY:
00453 if (ivalue) *ivalue = uu_ignreply;
00454 result = uu_ignreply;
00455 break;
00456 case UUOPT_DEBUG:
00457 if (ivalue) *ivalue = uu_debug;
00458 result = uu_debug;
00459 break;
00460 case UUOPT_ERRNO:
00461 if (ivalue) *ivalue = uu_errno;
00462 result = uu_errno;
00463 break;
00464 case UUOPT_OVERWRITE:
00465 if (ivalue) *ivalue = uu_overwrite;
00466 result = uu_overwrite;
00467 break;
00468 case UUOPT_SAVEPATH:
00469 _FP_strncpy (cvalue, uusavepath, clength);
00470 result = 0;
00471 break;
00472 case UUOPT_PROGRESS:
00473 if (clength==sizeof(uuprogress)) {
00474 memcpy (cvalue, &progress, sizeof (uuprogress));
00475 result = 0;
00476 }
00477 else
00478 result = -1;
00479 break;
00480 case UUOPT_IGNMODE:
00481 if (ivalue) *ivalue = uu_ignmode;
00482 result = uu_ignmode;
00483 break;
00484 case UUOPT_USETEXT:
00485 if (ivalue) *ivalue = uu_handletext;
00486 result = uu_handletext;
00487 break;
00488 case UUOPT_PREAMB:
00489 if (ivalue) *ivalue = uu_usepreamble;
00490 result = uu_usepreamble;
00491 break;
00492 case UUOPT_TINYB64:
00493 if (ivalue) *ivalue = uu_tinyb64;
00494 result = uu_tinyb64;
00495 break;
00496 case UUOPT_ENCEXT:
00497 _FP_strncpy (cvalue, uuencodeext, clength);
00498 result = 0;
00499 break;
00500 case UUOPT_REMOVE:
00501 if (ivalue) *ivalue = uu_remove_input;
00502 result = uu_remove_input;
00503 break;
00504 case UUOPT_MOREMIME:
00505 if (ivalue) *ivalue = uu_more_mime;
00506 result = uu_more_mime;
00507 break;
00508 default:
00509 return -1;
00510 }
00511 return result;
00512 }
00513
00514 int UUEXPORT
00515 UUSetOption (int option, int ivalue, char *cvalue)
00516 {
00517 switch (option) {
00518 case UUOPT_FAST:
00519 uu_fast_scanning = ivalue;
00520 break;
00521 case UUOPT_DUMBNESS:
00522 uu_dumbness = ivalue;
00523 break;
00524 case UUOPT_BRACKPOL:
00525 uu_bracket_policy = ivalue;
00526 break;
00527 case UUOPT_VERBOSE:
00528 uu_verbose = ivalue;
00529 break;
00530 case UUOPT_DESPERATE:
00531 uu_desperate = ivalue;
00532 break;
00533 case UUOPT_IGNREPLY:
00534 uu_ignreply = ivalue;
00535 break;
00536 case UUOPT_DEBUG:
00537 uu_debug = ivalue;
00538 break;
00539 case UUOPT_OVERWRITE:
00540 uu_overwrite = ivalue;
00541 break;
00542 case UUOPT_SAVEPATH:
00543 _FP_free (uusavepath);
00544 uusavepath = _FP_strdup (cvalue);
00545 break;
00546 case UUOPT_IGNMODE:
00547 uu_ignmode = ivalue;
00548 break;
00549 case UUOPT_USETEXT:
00550 uu_handletext = ivalue;
00551 break;
00552 case UUOPT_PREAMB:
00553 uu_usepreamble = ivalue;
00554 break;
00555 case UUOPT_TINYB64:
00556 uu_tinyb64 = ivalue;
00557 break;
00558 case UUOPT_ENCEXT:
00559 _FP_free (uuencodeext);
00560 uuencodeext = _FP_strdup (cvalue);
00561 break;
00562 case UUOPT_REMOVE:
00563 uu_remove_input = ivalue;
00564 break;
00565 case UUOPT_MOREMIME:
00566 uu_more_mime = ivalue;
00567 break;
00568 default:
00569 return UURET_ILLVAL;
00570 }
00571 return UURET_OK;
00572 }
00573
00574 char * UUEXPORT
00575 UUstrerror (int code)
00576 {
00577 return uuretcodes[code];
00578 }
00579
00580
00581
00582
00583
00584 int UUEXPORT
00585 UUSetMsgCallback (void *opaque,
00586 void (*func) _ANSI_ARGS_((void *, char *, int)))
00587 {
00588 uu_MsgCallback = func;
00589 uu_MsgCBArg = opaque;
00590
00591 return UURET_OK;
00592 }
00593
00594 int UUEXPORT
00595 UUSetBusyCallback (void *opaque,
00596 int (*func) _ANSI_ARGS_((void *, uuprogress *)),
00597 long msecs)
00598 {
00599 uu_BusyCallback = func;
00600 uu_BusyCBArg = opaque;
00601 uu_busy_msecs = msecs;
00602
00603 return UURET_OK;
00604 }
00605
00606 int UUEXPORT
00607 UUSetFileCallback (void *opaque,
00608 int (*func) _ANSI_ARGS_((void *, char *, char *, int)))
00609 {
00610 uu_FileCallback = func;
00611 uu_FileCBArg = opaque;
00612
00613 return UURET_OK;
00614 }
00615
00616 int UUEXPORT
00617 UUSetFNameFilter (void *opaque,
00618 char * (*func) _ANSI_ARGS_((void *, char *)))
00619 {
00620 uu_FNameFilter = func;
00621 uu_FFCBArg = opaque;
00622
00623 return UURET_OK;
00624 }
00625
00626
00627
00628
00629
00630
00631 uulist * UUEXPORT
00632 UUGetFileListItem (int item)
00633 {
00634 uulist *iter=UUGlobalFileList;
00635
00636 if (item 00637 return NULL;
00638 while (item && iter) {
00639 iter = iter->NEXT;
00640 item--;
00641 }
00642 return iter;
00643 }
00644
00645
00646
00647
00648
00649 char * UUEXPORT
00650 UUFNameFilter (char *fname)
00651 {
00652 if (uu_FNameFilter)
00653 return (*uu_FNameFilter) (uu_FFCBArg, fname);
00654
00655 return fname;
00656 }
00657
00658
00659
00660
00661
00662
00663 int UUEXPORT
00664 UULoadFile (char *filename, char *fileid, int delflag)
00665 {
00666 return UULoadFileWithPartNo(filename, fileid, delflag, -1);
00667 }
00668
00669 int UUEXPORT
00670 UULoadFileWithPartNo (char *filename, char *fileid, int delflag, int partno)
00671 {
00672 int res, sr, count=0;
00673 struct stat finfo;
00674 fileread *loaded;
00675 uufile *fload;
00676 itbd *killem;
00677 FILE *datei;
00678
00679 if ((datei = fopen (filename, "rb")) == NULL) {
00680 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
00681 uustring (S_NOT_OPEN_SOURCE),
00682 filename, strerror (uu_errno = errno));
00683 return UURET_IOERR;
00684 }
00685
00686 if (fstat (fileno(datei), &finfo) == -1) {
00687 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
00688 uustring (S_NOT_STAT_FILE),
00689 filename, strerror (uu_errno = errno));
00690 fclose (datei);
00691 return UURET_IOERR;
00692 }
00693
00694
00695
00696
00697
00698 if (delflag && fileid==NULL) {
00699 if ((killem = (itbd *) malloc (sizeof (itbd))) == NULL) {
00700 UUMessage (uulib_id, __LINE__, UUMSG_WARNING,
00701 uustring (S_OUT_OF_MEMORY), sizeof (itbd));
00702 }
00703 else if ((killem->fname = _FP_strdup (filename)) == NULL) {
00704 UUMessage (uulib_id, __LINE__, UUMSG_WARNING,
00705 uustring (S_OUT_OF_MEMORY), strlen(filename)+1);
00706 _FP_free (killem);
00707 }
00708 else {
00709 killem->NEXT = ftodel;
00710 ftodel = killem;
00711 }
00712 }
00713
00714 progress.action = 0;
00715 progress.partno = 0;
00716 progress.numparts = 1;
00717 progress.fsize = (long) ((finfo.st_size>0)?finfo.st_size:-1);
00718 progress.percent = 0;
00719 progress.foffset = 0;
00720 _FP_strncpy (progress.curfile,
00721 (strlen(filename)>255)?
00722 (filename+strlen(filename)-255):filename,
00723 256);
00724 progress.action = UUACT_SCANNING;
00725
00726 if (fileid == NULL)
00727 fileid = filename;
00728
00729 while (!feof (datei) && !ferror (datei)) {
00730
00731
00732
00733 res = fgetc (datei);
00734 if (feof (datei) || ferror (datei))
00735 break;
00736 else
00737 ungetc (res, datei);
00738
00739 if ((loaded = ScanPart (datei, fileid, &sr)) == NULL) {
00740 if (sr != UURET_NODATA && sr != UURET_OK && sr != UURET_CONT) {
00741 UUkillfread (loaded);
00742 if (sr != UURET_CANCEL) {
00743 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
00744 uustring (S_READ_ERROR), filename,
00745 strerror (uu_errno));
00746 }
00747 UUCheckGlobalList ();
00748 progress.action = 0;
00749 fclose (datei);
00750 return sr;
00751 }
00752 continue;
00753 }
00754
00755 if (ferror (datei)) {
00756 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
00757 uustring (S_READ_ERROR), filename,
00758 strerror (uu_errno = errno));
00759 UUCheckGlobalList ();
00760 progress.action = 0;
00761 fclose (datei);
00762 return UURET_IOERR;
00763 }
00764
00765 if (partno != -1)
00766 loaded->partno = partno;
00767
00768 if ((loaded->uudet == QP_ENCODED || loaded->uudet == PT_ENCODED) &&
00769 (loaded->filename == NULL || *(loaded->filename) == '\0') &&
00770 !uu_handletext && (loaded->flags&FL_PARTIAL)==0) {
00771
00772
00773
00774 UUkillfread (loaded);
00775 continue;
00776 }
00777
00778 if ((loaded->subject == NULL || *(loaded->subject) == '\0') &&
00779 (loaded->mimeid == NULL || *(loaded->mimeid) == '\0') &&
00780 (loaded->filename== NULL || *(loaded->filename)== '\0') &&
00781 (loaded->uudet == 0)) {
00782
00783
00784
00785 UUkillfread (loaded);
00786 if (uu_fast_scanning && sr != UURET_CONT) break;
00787 continue;
00788 }
00789
00790 if ((fload = UUPreProcessPart (loaded, &res)) == NULL) {
00791
00792
00793
00794 if (res != UURET_NODATA) {
00795 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
00796 uustring (S_READ_ERROR), filename,
00797 (res==UURET_IOERR)?strerror(uu_errno):UUstrerror(res));
00798 }
00799 UUkillfread (loaded);
00800 if (uu_fast_scanning && sr != UURET_CONT) break;
00801 continue;
00802 }
00803
00804 if ((loaded->subject && *(loaded->subject)) ||
00805 (loaded->mimeid && *(loaded->mimeid)) ||
00806 (loaded->filename&& *(loaded->filename))||
00807 (loaded->uudet)) {
00808 UUMessage (uulib_id, __LINE__, UUMSG_MESSAGE,
00809 uustring (S_LOADED_PART),
00810 filename,
00811 (loaded->subject) ? loaded->subject : "",
00812 (fload->subfname) ? fload->subfname : "",
00813 (loaded->filename) ? loaded->filename : "",
00814 fload->partno,
00815 (loaded->begin) ? "begin" : "",
00816 (loaded->end) ? "end" : "",
00817 codenames[loaded->uudet]);
00818 }
00819
00820 if ((res = UUInsertPartToList (fload))) {
00821
00822
00823
00824 UUkillfile (fload);
00825
00826 if (res != UURET_NODATA) {
00827 UUCheckGlobalList ();
00828 progress.action = 0;
00829 fclose (datei);
00830 return res;
00831 }
00832 if (uu_fast_scanning && sr != UURET_CONT)
00833 break;
00834
00835 continue;
00836 }
00837
00838
00839
00840
00841
00842
00843 if (uu_fast_scanning && sr != UURET_CONT)
00844 break;
00845
00846 if (loaded->uudet)
00847 count++;
00848 }
00849 if (ferror (datei)) {
00850 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
00851 uustring (S_READ_ERROR), filename,
00852 strerror (uu_errno = errno));
00853 UUCheckGlobalList ();
00854 progress.action = 0;
00855 fclose (datei);
00856 return UURET_IOERR;
00857 }
00858 fclose (datei);
00859
00860 if (!uu_fast_scanning && count==0) {
00861 UUMessage (uulib_id, __LINE__, UUMSG_NOTE,
00862 uustring (S_NO_DATA_FOUND), filename);
00863 }
00864
00865 progress.action = 0;
00866 UUCheckGlobalList ();
00867
00868 return UURET_OK;
00869 }
00870
00871
00872
00873
00874
00875 int UUEXPORT
00876 UUDecodeToTemp (uulist *thefile)
00877 {
00878 return UUDecode (thefile);
00879 }
00880
00881
00882
00883
00884
00885
00886
00887
00888 int UUEXPORT
00889 UUDecodeFile (uulist *thefile, char *destname)
00890 {
00891 FILE *target, *source;
00892 struct stat finfo;
00893 int fildes, res;
00894 size_t bytes;
00895
00896 if (thefile == NULL)
00897 return UURET_ILLVAL;
00898
00899 if ((res = UUDecode (thefile)) != UURET_OK)
00900 if (res != UURET_NOEND || !uu_desperate)
00901 return res;
00902
00903 if (thefile->binfile == NULL) {
00904 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
00905 uustring (S_NO_BIN_FILE));
00906 return UURET_IOERR;
00907 }
00908
00909 if ((source = fopen (thefile->binfile, "rb")) == NULL) {
00910 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
00911 uustring (S_NOT_OPEN_FILE),
00912 thefile->binfile, strerror (uu_errno = errno));
00913 return UURET_IOERR;
00914 }
00915
00916
00917
00918
00919
00920 if ((thefile->mode & 0777) != thefile->mode) {
00921 UUMessage (uulib_id, __LINE__, UUMSG_NOTE,
00922 uustring (S_STRIPPED_SETUID),
00923 destname, (int)thefile->mode);
00924 thefile->mode &= 0777;
00925 }
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938 if (destname)
00939 strcpy (uugen_fnbuffer, destname);
00940 else {
00941 sprintf (uugen_fnbuffer, "%s%s",
00942 (uusavepath)?uusavepath:"",
00943 UUFNameFilter ((thefile->filename)?
00944 thefile->filename:"unknown.xxx"));
00945 }
00946
00947
00948
00949
00950
00951 if (!uu_overwrite) {
00952 if (stat (uugen_fnbuffer, &finfo) == 0) {
00953 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
00954 uustring (S_TARGET_EXISTS), uugen_fnbuffer);
00955 fclose (source);
00956 return UURET_EXISTS;
00957 }
00958 }
00959
00960 if (fstat (fileno(source), &finfo) == -1) {
00961 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
00962 uustring (S_NOT_STAT_FILE),
00963 thefile->binfile, strerror (uu_errno = errno));
00964 fclose (source);
00965 return UURET_IOERR;
00966 }
00967
00968 progress.action = 0;
00969 _FP_strncpy (progress.curfile,
00970 (strlen(uugen_fnbuffer)>255)?
00971 (uugen_fnbuffer+strlen(uugen_fnbuffer)-255):uugen_fnbuffer,
00972 256);
00973 progress.partno = 0;
00974 progress.numparts = 1;
00975 progress.fsize = (long) ((finfo.st_size)?finfo.st_size:-1);
00976 progress.foffset = 0;
00977 progress.percent = 0;
00978 progress.action = UUACT_COPYING;
00979
00980 if ((fildes = open (uugen_fnbuffer,
00981 O_WRONLY | O_CREAT | O_BINARY | O_TRUNC,
00982 (uu_ignmode)?0666:thefile->mode)) == -1) {
00983 progress.action = 0;
00984 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
00985 uustring (S_NOT_OPEN_TARGET),
00986 uugen_fnbuffer, strerror (uu_errno = errno));
00987 fclose (source);
00988 return UURET_IOERR;
00989 }
00990
00991 if (rename(thefile->binfile, uugen_fnbuffer) == 0) {
00992 fclose(source);
00993 close(fildes);
00994 goto finish_ok;
00995 }
00996
00997 if ((target = fdopen (fildes, "wb")) == NULL) {
00998 progress.action = 0;
00999 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
01000 uustring (S_IO_ERR_TARGET),
01001 uugen_fnbuffer, strerror (uu_errno = errno));
01002 fclose (source);
01003 close (fildes);
01004 return UURET_IOERR;
01005 }
01006
01007 while (!feof (source)) {
01008
01009 if (UUBUSYPOLL(ftell(source),progress.fsize)) {
01010 UUMessage (uulib_id, __LINE__, UUMSG_NOTE,
01011 uustring (S_DECODE_CANCEL));
01012 fclose (source);
01013 fclose (target);
01014 unlink (uugen_fnbuffer);
01015 return UURET_CANCEL;
01016 }
01017
01018 bytes = fread (uugen_inbuffer, 1, 1024, source);
01019
01020 if (ferror (source) || (bytes == 0 && !feof (source))) {
01021 progress.action = 0;
01022 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
01023 uustring (S_READ_ERROR),
01024 thefile->binfile, strerror (uu_errno = errno));
01025 fclose (source);
01026 fclose (target);
01027 unlink (uugen_fnbuffer);
01028 return UURET_IOERR;
01029 }
01030 if (fwrite (uugen_inbuffer, 1, bytes, target) != bytes) {
01031 progress.action = 0;
01032 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
01033 uustring (S_WR_ERR_TARGET),
01034 uugen_fnbuffer, strerror (uu_errno = errno));
01035 fclose (source);
01036 fclose (target);
01037 unlink (uugen_fnbuffer);
01038 return UURET_IOERR;
01039 }
01040 }
01041
01042 fclose (source);
01043 if (fclose (target)) {
01044 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
01045 uustring (S_WR_ERR_TARGET),
01046 uugen_fnbuffer, strerror (uu_errno = errno));
01047 unlink (uugen_fnbuffer);
01048 return UURET_IOERR;
01049 }
01050
01051
01052
01053
01054
01055 if (unlink (thefile->binfile)) {
01056 UUMessage (uulib_id, __LINE__, UUMSG_WARNING,
01057 uustring (S_TMP_NOT_REMOVED),
01058 thefile->binfile,
01059 strerror (uu_errno = errno));
01060 }
01061
01062 finish_ok:
01063 _FP_free (thefile->binfile);
01064 thefile->binfile = NULL;
01065 thefile->state &= ~UUFILE_TMPFILE;
01066 thefile->state |= UUFILE_DECODED;
01067 progress.action = 0;
01068
01069 return UURET_OK;
01070 }
01071
01072
01073
01074
01075
01076
01077 int UUEXPORT
01078 UUInfoFile (uulist *thefile, void *opaque,
01079 int (*func) _ANSI_ARGS_((void *, char *)))
01080 {
01081 int errflag=0, res, bhflag=0, dd;
01082 long maxpos;
01083 FILE *inpfile;
01084
01085
01086
01087
01088
01089 if (uu_FileCallback) {
01090 if ((res = (*uu_FileCallback) (uu_FileCBArg,
01091 thefile->thisfile->data->sfname,
01092 uugen_fnbuffer,
01093 1)) != UURET_OK)
01094 return res;
01095 if ((inpfile = fopen (uugen_fnbuffer, "rb")) == NULL) {
01096 (*uu_FileCallback) (uu_FileCBArg, thefile->thisfile->data->sfname,
01097 uugen_fnbuffer, 0);
01098 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
01099 uustring (S_NOT_OPEN_FILE), uugen_fnbuffer,
01100 strerror (uu_errno = errno));
01101 return UURET_IOERR;
01102 }
01103 }
01104 else {
01105 if ((inpfile = fopen (thefile->thisfile->data->sfname, "rb")) == NULL) {
01106 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
01107 uustring (S_NOT_OPEN_FILE),
01108 thefile->thisfile->data->sfname,
01109 strerror (uu_errno=errno));
01110 return UURET_IOERR;
01111 }
01112 _FP_strncpy (uugen_fnbuffer, thefile->thisfile->data->sfname, 1024);
01113 }
01114
01115
01116
01117
01118
01119 fseek (inpfile, thefile->thisfile->data->startpos, SEEK_SET);
01120 maxpos = thefile->thisfile->data->startpos + thefile->thisfile->data->length;
01121
01122 while (!feof (inpfile) &&
01123 (uu_fast_scanning || ftell(inpfile) 01124 if (_FP_fgets (uugen_inbuffer, 511, inpfile) == NULL)
01125 break;
01126 uugen_inbuffer[511] = '\0';
01127
01128 if (ferror (inpfile))
01129 break;
01130
01131 dd = UUValidData (uugen_inbuffer, 0, &bhflag);
01132
01133 if (thefile->uudet == B64ENCODED && dd == B64ENCODED)
01134 break;
01135 else if (thefile->uudet == BH_ENCODED && bhflag)
01136 break;
01137 else if ((thefile->uudet == UU_ENCODED || thefile->uudet == XX_ENCODED) &&
01138 strncmp (uugen_inbuffer, "begin ", 6) == 0)
01139 break;
01140 else if (thefile->uudet == YENC_ENCODED &&
01141 strncmp (uugen_inbuffer, "=ybegin ", 8) == 0)
01142 break;
01143
01144 if ((*func) (opaque, uugen_inbuffer))
01145 break;
01146 }
01147
01148 if (ferror (inpfile)) {
01149 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
01150 uustring (S_READ_ERROR),
01151 uugen_fnbuffer, strerror (uu_errno = errno));
01152 errflag = 1;
01153 }
01154
01155 fclose (inpfile);
01156
01157 if (uu_FileCallback)
01158 (*uu_FileCallback) (uu_FileCBArg,
01159 thefile->thisfile->data->sfname,
01160 uugen_fnbuffer, 0);
01161
01162 if (errflag)
01163 return UURET_IOERR;
01164
01165 return UURET_OK;
01166 }
01167
01168 int UUEXPORT
01169 UURenameFile (uulist *thefile, char *newname)
01170 {
01171 char *oldname;
01172
01173 if (thefile == NULL)
01174 return UURET_ILLVAL;
01175
01176 oldname = thefile->filename;
01177
01178 if ((thefile->filename = _FP_strdup (newname)) == NULL) {
01179 UUMessage (uulib_id, __LINE__, UUMSG_ERROR,
01180 uustring (S_NOT_RENAME),
01181 oldname, newname);
01182 thefile->filename = oldname;
01183 return UURET_NOMEM;
01184 }
01185 _FP_free (oldname);
01186 return UURET_OK;
01187 }
01188
01189 int UUEXPORT
01190 UURemoveTemp (uulist *thefile)
01191 {
01192 if (thefile == NULL)
01193 return UURET_ILLVAL;
01194
01195 if (thefile->binfile) {
01196 if (unlink (thefile->binfile)) {
01197 UUMessage (uulib_id, __LINE__, UUMSG_WARNING,
01198 uustring (S_TMP_NOT_REMOVED),
01199 thefile->binfile,
01200 strerror (uu_errno = errno));
01201 }
01202 _FP_free (thefile->binfile);
01203 thefile->binfile = NULL;
01204 thefile->state &= ~UUFILE_TMPFILE;
01205 }
01206 return UURET_OK;
01207 }
01208
01209 int UUEXPORT
01210 UUCleanUp (void)
01211 {
01212 itbd *iter=ftodel, *ptr;
01213 uulist *liter;
01214 uufile *fiter;
01215 allomap *aiter;
01216
01217
01218
01219
01220
01221 while (iter) {
01222 if (unlink (iter->fname)) {
01223 UUMessage (uulib_id, __LINE__, UUMSG_WARNING,
01224 uustring (S_TMP_NOT_REMOVED),
01225 iter->fname, strerror (uu_errno = errno));
01226 }
01227 _FP_free (iter->fname);
01228 ptr = iter;
01229 iter = iter->NEXT;
01230 _FP_free (ptr);
01231 }
01232
01233 ftodel = NULL;
01234
01235
01236
01237
01238
01239 if (uu_remove_input) {
01240 liter = UUGlobalFileList;
01241 while (liter) {
01242 if (liter->state & UUFILE_DECODED) {
01243 fiter = liter->thisfile;
01244 while (fiter) {
01245 if (fiter->data && fiter->data->sfname) {
01246
01247
01248
01249
01250 unlink (fiter->data->sfname);
01251 }
01252 fiter = fiter->NEXT;
01253 }
01254 }
01255 liter = liter->NEXT;
01256 }
01257 }
01258
01259 UUkilllist (UUGlobalFileList);
01260 UUGlobalFileList = NULL;
01261
01262 _FP_free (uusavepath);
01263 _FP_free (uuencodeext);
01264 _FP_free (sstate.source);
01265
01266 uusavepath = NULL;
01267 uuencodeext = NULL;
01268
01269 UUkillheaders (&localenv);
01270 UUkillheaders (&sstate.envelope);
01271 memset (&localenv, 0, sizeof (headers));
01272 memset (&sstate, 0, sizeof (scanstate));
01273
01274 while (mssdepth) {
01275 mssdepth--;
01276 UUkillheaders (&(multistack[mssdepth].envelope));
01277 _FP_free (multistack[mssdepth].source);
01278 }
01279
01280
01281
01282
01283
01284 for (aiter=toallocate; aiter->ptr; aiter++) {
01285 _FP_free (*(aiter->ptr));
01286 *(aiter->ptr) = NULL;
01287 }
01288
01289 return UURET_OK;
01290 }
01291