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 #include
00033 #include
00034 #include
00035 #include
00036 #include
00037
00038 #ifdef STDC_HEADERS
00039 #include
00040 #include
00041 #endif
00042 #ifdef HAVE_UNISTD_H
00043 #include
00044 #endif
00045 #ifdef HAVE_ERRNO_H
00046 #include
00047 #endif
00048
00049 #include uudeview.h>
00050 #include uuint.h>
00051 #include fptools.h>
00052 #include uustring.h>
00053 #include crc32.h>
00054
00055
00056 #ifndef SEEK_SET
00057 #ifdef L_BEGIN
00058 #define SEEK_SET L_BEGIN
00059 #else
00060 #define SEEK_SET 0
00061 #endif
00062 #endif
00063
00064 char * uuencode_id = "$Id: uuencode.c 260 2007-05-04 23:32:54Z csk $";
00065
00066 #if 0
00067
00068
00069
00070
00071
00072
00073
00074 #ifndef EOLSTRING
00075 #define EOLSTRING "\015\012"
00076 #endif
00077
00078 #else
00079
00080
00081
00082
00083
00084
00085
00086
00087 #ifndef EOLSTRING
00088 #define EOLSTRING "\n"
00089 #endif
00090
00091 #endif
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 #ifdef EOLSTRING
00106 static unsigned char *eolstring = (unsigned char *) EOLSTRING;
00107 #else
00108 static unsigned char *eolstring = (unsigned char *) "\012";
00109 #endif
00110
00111
00112
00113
00114
00115 #define CTE_UUENC "x-uuencode"
00116 #define CTE_XXENC "x-xxencode"
00117 #define CTE_BINHEX "x-binhex"
00118 #define CTE_YENC "x-yenc"
00119
00120 #define CTE_TYPE(y) (((y)==B64ENCODED) ? "Base64" : \
00121 ((y)==UU_ENCODED) ? CTE_UUENC : \
00122 ((y)==XX_ENCODED) ? CTE_XXENC : \
00123 ((y)==PT_ENCODED) ? "8bit" : \
00124 ((y)==QP_ENCODED) ? "quoted-printable" : \
00125 ((y)==BH_ENCODED) ? CTE_BINHEX : \
00126 ((y)==YENC_ENCODED) ? CTE_YENC : "x-oops")
00127
00128
00129
00130
00131
00132 unsigned char UUEncodeTable[64] = {
00133 '`', '!', '"', '#', '$', '%', '&', '\'',
00134 '(', ')', '*', '+', ',', '-', '.', '/',
00135 '0', '1', '2', '3', '4', '5', '6', '7',
00136 '8', '9', ':', ';', ', '=', '>', '?',
00137 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
00138 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
00139 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
00140 'X', 'Y', 'Z', '[', '\\',']', '^', '_'
00141 };
00142
00143
00144 unsigned char B64EncodeTable[64] = {
00145 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
00146 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
00147 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
00148 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
00149 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
00150 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
00151 'w', 'x', 'y', 'z', '0', '1', '2', '3',
00152 '4', '5', '6', '7', '8', '9', '+', '/'
00153 };
00154
00155 unsigned char XXEncodeTable[64] = {
00156 '+', '-', '0', '1', '2', '3', '4', '5',
00157 '6', '7', '8', '9', 'A', 'B', 'C', 'D',
00158 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
00159 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
00160 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
00161 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
00162 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
00163 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
00164 };
00165
00166 unsigned char BHEncodeTable[64] = {
00167 '!', '"', '#', '$', '%', '&', '\'', '(',
00168 ')', '*', '+', ',', '-', '0', '1', '2',
00169 '3', '4', '5', '6', '8', '9', '@', 'A',
00170 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
00171 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R',
00172 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', '[',
00173 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'h',
00174 'i', 'j', 'k', 'l', 'm', 'p', 'q', 'r'
00175 };
00176
00177 unsigned char HexEncodeTable[16] = {
00178 '0', '1', '2', '3', '4', '5', '6', '7',
00179 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
00180 };
00181
00182 typedef struct {
00183 char *extension;
00184 char *mimetype;
00185 } mimemap;
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 static mimemap mimetable[] = {
00196 { "gif", "image/gif" },
00197 { "jpg", "image/jpeg" },
00198 { "jpeg", "image/jpeg" },
00199 { "tif", "image/tiff" },
00200 { "tiff", "image/tiff" },
00201 { "cgm", "image/cgm" },
00202 { "au", "audio/basic" },
00203 { "mov", "video/quicktime" },
00204 { "qt", "video/quicktime" },
00205 { "mpeg", "video/mpeg" },
00206 { "mpg", "video/mpeg" },
00207 { "mp2", "video/mpeg" },
00208 { "mp3", "audio/mpeg" },
00209 { "ps", "application/postscript" },
00210 { "zip", "application/zip" },
00211 { "doc", "application/msword"},
00212 { NULL, NULL }
00213 };
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 static int bpl[8] = { 0, 45, 57, 45, 45, 0, 0, 128 };
00225
00226
00227
00228
00229
00230 static unsigned char *etables[5] = {
00231 NULL,
00232 UUEncodeTable,
00233 B64EncodeTable,
00234 XXEncodeTable,
00235 BHEncodeTable
00236 };
00237
00238
00239
00240
00241
00242 char *uuestr_itemp;
00243 char *uuestr_otemp;
00244
00245
00246
00247
00248
00249 static int
00250 UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc32_t *crc, crc32_t *pcrc)
00251 {
00252 unsigned char *itemp = (unsigned char *) uuestr_itemp;
00253 unsigned char *otemp = (unsigned char *) uuestr_otemp;
00254 unsigned char *optr, *table, *tptr;
00255 int index, count;
00256 long line=0;
00257 size_t llen;
00258
00259 if (outfile==NULL || infile==NULL ||
00260 (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
00261 encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) {
00262 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
00263 uustring (S_PARM_CHECK), "UUEncodeStream()");
00264 return UURET_ILLVAL;
00265 }
00266
00267
00268
00269
00270
00271
00272 if (encoding == PT_ENCODED || encoding == QP_ENCODED) {
00273 while (!feof (infile) && (linperfile 00274 if (_FP_fgets ((char*)itemp, 255, infile) == NULL) {
00275 break;
00276 }
00277
00278 itemp[255] = '\0';
00279 count = strlen ((char*)itemp);
00280
00281 llen = 0;
00282 optr = otemp;
00283
00284
00285
00286
00287
00288 if (UUBUSYPOLL(ftell(infile)-progress.foffset,progress.fsize)) {
00289 UUMessage (uuencode_id, __LINE__, UUMSG_NOTE,
00290 uustring (S_ENCODE_CANCEL));
00291 return UURET_CANCEL;
00292 }
00293
00294 if (encoding == PT_ENCODED) {
00295
00296
00297
00298 if (count > 0 && itemp[count-1] == '\n') {
00299 const size_t n = strlen ((char*) eolstring);
00300 itemp[--count] = '\0';
00301 if (fwrite (itemp, 1, count, outfile) != count ||
00302 fwrite ((char *) eolstring, 1, n, outfile) != n) {
00303 return UURET_IOERR;
00304 }
00305 }
00306 else {
00307 if (fwrite (itemp, 1, count, outfile) != llen) {
00308 return UURET_IOERR;
00309 }
00310 }
00311 }
00312 else if (encoding == QP_ENCODED) {
00313 for (index=0; index00314 if (llen == 0 && itemp[index] == '.') {
00315
00316
00317
00318
00319 *optr++ = '=';
00320 *optr++ = HexEncodeTable[itemp[index] >> 4];
00321 *optr++ = HexEncodeTable[itemp[index] & 0x0f];
00322 llen += 3;
00323 }
00324 else if ((itemp[index] >= 33 && itemp[index] 00325 (itemp[index] >= 62 && itemp[index] 00326 itemp[index] == 9 || itemp[index] == 32) {
00327 *optr++ = itemp[index];
00328 llen++;
00329 }
00330 else if (itemp[index] == '\n') {
00331
00332
00333
00334
00335
00336
00337 if (index>0 && (itemp[index-1] == 9 || itemp[index-1] == 32)) {
00338 *(optr-1) = '=';
00339 if (llen 00340 *optr++ = HexEncodeTable[itemp[index-1] >> 4];
00341 *optr++ = HexEncodeTable[itemp[index-1] & 0x0f];
00342 llen += 2;
00343 }
00344 }
00345
00346 if (fwrite (otemp, 1, llen, outfile) != llen ||
00347 fwrite ((char *) eolstring, 1,
00348 strlen((char*)eolstring), outfile) != strlen ((char*)eolstring)) {
00349 return UURET_IOERR;
00350 }
00351
00352
00353
00354
00355
00356 if (index>0 && (itemp[index-1] == 9 || itemp[index-1] == 32) &&
00357 *(optr-1) == '=') {
00358 otemp[0] = '=';
00359 otemp[1] = HexEncodeTable[itemp[index-1] >> 4];
00360 otemp[2] = HexEncodeTable[itemp[index-1] & 0x0f];
00361
00362 if (fwrite (otemp, 1, 3, outfile) != 3 ||
00363 fwrite ((char *) eolstring, 1,
00364 strlen((char*)eolstring), outfile) != strlen ((char*)eolstring)) {
00365 return UURET_IOERR;
00366 }
00367 }
00368
00369 optr = otemp;
00370 llen = 0;
00371 }
00372 else {
00373 *optr++ = '=';
00374 *optr++ = HexEncodeTable[itemp[index] >> 4];
00375 *optr++ = HexEncodeTable[itemp[index] & 0x0f];
00376 llen += 3;
00377 }
00378
00379
00380
00381
00382
00383
00384
00385 if (itemp[index+1] != 0 && itemp[index+1] != '\n' &&
00386 (llen >= 75 ||
00387 (!((itemp[index+1] >= 33 && itemp[index+1] 00388 (itemp[index+1] >= 62 && itemp[index+1] 00389 llen >= 73))) {
00390
00391 *optr++ = '=';
00392 llen++;
00393
00394 if (fwrite (otemp, 1, llen, outfile) != llen ||
00395 fwrite ((char *) eolstring, 1,
00396 strlen((char*)eolstring), outfile) != strlen ((char*)eolstring)) {
00397 return UURET_IOERR;
00398 }
00399
00400 optr = otemp;
00401 llen = 0;
00402 }
00403 }
00404 }
00405
00406 line++;
00407 }
00408
00409 return UURET_OK;
00410 }
00411
00412
00413
00414
00415
00416 if (encoding == YENC_ENCODED) {
00417 llen = 0;
00418 optr = otemp;
00419
00420 while (!feof (infile) && (linperfile 00421 if ((count = fread (itemp, 1, 128, infile)) != 128) {
00422 if (count == 0) {
00423 break;
00424 }
00425 else if (ferror (infile)) {
00426 return UURET_IOERR;
00427 }
00428 }
00429
00430 if (pcrc)
00431 *pcrc = crc32(*pcrc, itemp, count);
00432 if (crc)
00433 *crc = crc32(*crc, itemp, count);
00434
00435 line++;
00436
00437
00438
00439
00440
00441 if (UUBUSYPOLL(ftell(infile)-progress.foffset,progress.fsize)) {
00442 UUMessage (uuencode_id, __LINE__, UUMSG_NOTE,
00443 uustring (S_ENCODE_CANCEL));
00444 return UURET_CANCEL;
00445 }
00446
00447 for (index=0; index00448 if (llen > 127) {
00449 if (fwrite (otemp, 1, llen, outfile) != llen ||
00450 fwrite ((char *) eolstring, 1,
00451 strlen((char*)eolstring), outfile) != strlen ((char*)eolstring)) {
00452 return UURET_IOERR;
00453 }
00454 llen = 0;
00455 optr = otemp;
00456 }
00457
00458 switch ((char) ((int) itemp[index] + 42)) {
00459 case '\0':
00460 case '\t':
00461 case '\n':
00462 case '\r':
00463 case '=':
00464 case '\033':
00465 *optr++ = '=';
00466 *optr++ = (char) ((int) itemp[index] + 42 + 64);
00467 llen += 2;
00468 break;
00469
00470 case '.':
00471 if (llen == 0) {
00472 *optr++ = '=';
00473 *optr++ = (char) ((int) itemp[index] + 42 + 64);
00474 llen += 2;
00475 }
00476 else {
00477 *optr++ = (char) ((int) itemp[index] + 42);
00478 llen++;
00479 }
00480 break;
00481
00482 default:
00483 *optr++ = (char) ((int) itemp[index] + 42);
00484 llen++;
00485 break;
00486 }
00487 }
00488 }
00489
00490
00491
00492
00493
00494 if (llen) {
00495 if (fwrite (otemp, 1, llen, outfile) != llen ||
00496 fwrite ((char *) eolstring, 1,
00497 strlen((char*)eolstring), outfile) != strlen ((char*)eolstring)) {
00498 return UURET_IOERR;
00499 }
00500 }
00501
00502 return UURET_OK;
00503 }
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513 table = etables[encoding];
00514
00515 if (table==NULL || bpl[encoding]==0) {
00516 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
00517 uustring (S_PARM_CHECK), "UUEncodeStream()");
00518 return UURET_ILLVAL;
00519 }
00520
00521 while (!feof (infile) && (linperfile 00522 if ((count = fread (itemp, 1, bpl[encoding], infile)) != bpl[encoding]) {
00523 if (count == 0)
00524 break;
00525 else if (ferror (infile))
00526 return UURET_IOERR;
00527 }
00528
00529 optr = otemp;
00530 llen = 0;
00531
00532
00533
00534
00535
00536 if (UUBUSYPOLL(ftell(infile)-progress.foffset,progress.fsize)) {
00537 UUMessage (uuencode_id, __LINE__, UUMSG_NOTE,
00538 uustring (S_ENCODE_CANCEL));
00539 return UURET_CANCEL;
00540 }
00541
00542
00543
00544
00545
00546 if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
00547 *optr++ = table[count];
00548 llen++;
00549 }
00550
00551
00552
00553
00554
00555 for (index=0; index00556 *optr++ = table[itemp[index] >> 2];
00557 *optr++ = table[((itemp[index ] & 0x03) > 4)];
00558 *optr++ = table[((itemp[index+1] & 0x0f) > 6)];
00559 *optr++ = table[ itemp[index+2] & 0x3f];
00560 }
00561
00562
00563
00564
00565
00566 if (index != count) {
00567 if (encoding == B64ENCODED) {
00568 if (count - index == 2) {
00569 *optr++ = table[itemp[index] >> 2];
00570 *optr++ = table[((itemp[index ] & 0x03) 00571 ((itemp[index+1] & 0xf0) >> 4)];
00572 *optr++ = table[((itemp[index+1] & 0x0f) 00573 *optr++ = '=';
00574 }
00575 else if (count - index == 1) {
00576 *optr++ = table[ itemp[index] >> 2];
00577 *optr++ = table[(itemp[index] & 0x03) 00578 *optr++ = '=';
00579 *optr++ = '=';
00580 }
00581 llen += 4;
00582 }
00583 else if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
00584 if (count - index == 2) {
00585 *optr++ = table[itemp[index] >> 2];
00586 *optr++ = table[((itemp[index ] & 0x03) 00587 ( itemp[index+1] >> 4)];
00588 *optr++ = table[((itemp[index+1] & 0x0f) 00589 *optr++ = table[0];
00590 }
00591 else if (count - index == 1) {
00592 *optr++ = table[ itemp[index] >> 2];
00593 *optr++ = table[(itemp[index] & 0x03) 00594 *optr++ = table[0];
00595 *optr++ = table[0];
00596 }
00597 llen += 4;
00598 }
00599 }
00600
00601
00602
00603
00604
00605 tptr = eolstring;
00606
00607 while (*tptr)
00608 *optr++ = *tptr++;
00609
00610 *optr++ = '\0';
00611 llen += strlen ((char *) eolstring);
00612
00613 if (fwrite (otemp, 1, llen, outfile) != llen)
00614 return UURET_IOERR;
00615
00616 line++;
00617 }
00618 return UURET_OK;
00619 }
00620
00621
00622
00623
00624
00625 int UUEXPORT
00626 UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding,
00627 char *outfname, char *mimetype, int filemode)
00628 {
00629 mimemap *miter=mimetable;
00630 struct stat finfo;
00631 int res, themode;
00632 FILE *theifile;
00633 char *ptr;
00634 crc32_t crc;
00635 crc32_t *crcptr=NULL;
00636
00637 if (outfile==NULL ||
00638 (infile == NULL && infname==NULL) ||
00639 (outfname==NULL && infname==NULL) ||
00640 (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
00641 encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) {
00642 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
00643 uustring (S_PARM_CHECK), "UUEncodeMulti()");
00644 return UURET_ILLVAL;
00645 }
00646
00647 progress.action = 0;
00648
00649 if (infile==NULL) {
00650 if (stat (infname, &finfo) == -1) {
00651 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
00652 uustring (S_NOT_STAT_FILE),
00653 infname, strerror (uu_errno=errno));
00654 return UURET_IOERR;
00655 }
00656 if ((theifile = fopen (infname, "rb")) == NULL) {
00657 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
00658 uustring (S_NOT_OPEN_FILE),
00659 infname, strerror (uu_errno=errno));
00660 return UURET_IOERR;
00661 }
00662 themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777);
00663 progress.fsize = (long) finfo.st_size;
00664 }
00665 else {
00666 if (fstat (fileno (infile), &finfo) != 0) {
00667 themode = (filemode)?filemode:0644;
00668 progress.fsize = -1;
00669 }
00670 else {
00671 themode = (int) finfo.st_mode & 0777;
00672 progress.fsize = (long) finfo.st_size;
00673 }
00674 theifile = infile;
00675 }
00676
00677 if (progress.fsize 00678 progress.fsize = -1;
00679
00680 _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256);
00681
00682 progress.partno = 1;
00683 progress.numparts = 1;
00684 progress.percent = 0;
00685 progress.foffset = 0;
00686 progress.action = UUACT_ENCODING;
00687
00688
00689
00690
00691
00692
00693
00694 if (mimetype == NULL) {
00695 if ((ptr = _FP_strrchr ((outfname)?outfname:infname, '.'))) {
00696 while (miter->extension && _FP_stricmp (ptr+1, miter->extension) != 0)
00697 miter++;
00698 mimetype = miter->mimetype;
00699 }
00700 }
00701
00702 if (mimetype == NULL && (encoding == PT_ENCODED || encoding == QP_ENCODED)) {
00703 mimetype = "text/plain";
00704 }
00705
00706
00707
00708
00709
00710 if (encoding != YENC_ENCODED) {
00711 fprintf (outfile, "Content-Type: %s%s",
00712 (mimetype)?mimetype:"Application/Octet-Stream",
00713 eolstring);
00714 fprintf (outfile, "Content-Transfer-Encoding: %s%s",
00715 CTE_TYPE(encoding), eolstring);
00716 fprintf (outfile, "Content-Disposition: attachment; filename=\"%s\"%s",
00717 UUFNameFilter ((outfname)?outfname:infname), eolstring);
00718 fprintf (outfile, "%s", eolstring);
00719 }
00720
00721 if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
00722 fprintf (outfile, "begin %o %s%s",
00723 (themode) ? themode : 0644,
00724 UUFNameFilter ((outfname)?outfname:infname),
00725 eolstring);
00726 }
00727 else if (encoding == YENC_ENCODED) {
00728 crc = crc32(0L, Z_NULL, 0);
00729 crcptr = &crc;
00730 if (progress.fsize == -1) {
00731 fprintf (outfile, "=ybegin line=128 name=%s%s",
00732 UUFNameFilter ((outfname)?outfname:infname),
00733 eolstring);
00734 }
00735 else {
00736 fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s",
00737 progress.fsize,
00738 UUFNameFilter ((outfname)?outfname:infname),
00739 eolstring);
00740 }
00741 }
00742
00743 if ((res = UUEncodeStream (outfile, theifile, encoding, 0, crcptr, NULL)) != UURET_OK) {
00744 if (res != UURET_CANCEL) {
00745 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
00746 uustring (S_ERR_ENCODING),
00747 UUFNameFilter ((infname)?infname:outfname),
00748 (res==UURET_IOERR)?strerror(uu_errno):UUstrerror(res));
00749 }
00750 progress.action = 0;
00751 return res;
00752 }
00753
00754 if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
00755 fprintf (outfile, "%c%s",
00756 (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0],
00757 eolstring);
00758 fprintf (outfile, "end%s", eolstring);
00759 }
00760 else if (encoding == YENC_ENCODED) {
00761 if (progress.fsize == -1) {
00762 fprintf (outfile, "=yend crc32=%08lx%s",
00763 crc,
00764 eolstring);
00765 }
00766 else {
00767 fprintf (outfile, "=yend size=%ld crc32=%08lx%s",
00768 progress.fsize,
00769 crc,
00770 eolstring);
00771 }
00772 }
00773
00774
00775
00776
00777
00778 fprintf (outfile, "%s", eolstring);
00779
00780 if (infile==NULL)
00781 fclose (theifile);
00782
00783 progress.action = 0;
00784 return UURET_OK;
00785 }
00786
00787
00788
00789
00790
00791 int UUEXPORT
00792 UUEncodePartial (FILE *outfile, FILE *infile,
00793 char *infname, int encoding,
00794 char *outfname, char *mimetype,
00795 int filemode, int partno, long linperfile,
00796 crc32_t *crcptr)
00797 {
00798 mimemap *miter=mimetable;
00799 static FILE *theifile;
00800 int themode, numparts=1;
00801 struct stat finfo;
00802 long thesize;
00803 char *ptr;
00804 int res;
00805 crc32_t pcrc;
00806 crc32_t *pcrcptr=NULL;
00807
00808 if ((outfname==NULL&&infname==NULL) || partno00809 (infile == NULL&&infname==NULL) || outfile==NULL ||
00810 (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
00811 encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) {
00812 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
00813 uustring (S_PARM_CHECK), "UUEncodePartial()");
00814 return UURET_ILLVAL;
00815 }
00816
00817
00818
00819
00820
00821 progress.action = 0;
00822
00823 if (partno == 1) {
00824 if (infile==NULL) {
00825 if (stat (infname, &finfo) == -1) {
00826 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
00827 uustring (S_NOT_STAT_FILE),
00828 infname, strerror (uu_errno=errno));
00829 return UURET_IOERR;
00830 }
00831 if ((theifile = fopen (infname, "rb")) == NULL) {
00832 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
00833 uustring (S_NOT_OPEN_FILE),
00834 infname, strerror (uu_errno=errno));
00835 return UURET_IOERR;
00836 }
00837 if (linperfile 00838 numparts = 1;
00839 else
00840 numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/
00841 (linperfile*bpl[encoding]));
00842
00843 themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777);
00844 thesize = (long) finfo.st_size;
00845 }
00846 else {
00847 if (fstat (fileno (infile), &finfo) != 0) {
00848 UUMessage (uuencode_id, __LINE__, UUMSG_WARNING,
00849 uustring (S_STAT_ONE_PART));
00850 numparts = 1;
00851 themode = (filemode)?filemode:0644;
00852 thesize = -1;
00853 }
00854 else {
00855 if (linperfile 00856 numparts = 1;
00857 else
00858 numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/
00859 (linperfile*bpl[encoding]));
00860
00861 themode = (int) finfo.st_mode & 0777;
00862 thesize = (long) finfo.st_size;
00863 }
00864 theifile = infile;
00865 }
00866
00867 _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256);
00868
00869 progress.totsize = (thesize>=0) ? thesize : -1;
00870 progress.partno = 1;
00871 progress.numparts = numparts;
00872 progress.percent = 0;
00873 progress.foffset = 0;
00874
00875
00876
00877
00878
00879
00880
00881 if (mimetype == NULL) {
00882 if ((ptr = _FP_strrchr ((outfname)?outfname:infname, '.'))) {
00883 while (miter->extension && _FP_stricmp (ptr+1, miter->extension) != 0)
00884 miter++;
00885 mimetype = miter->mimetype;
00886 }
00887 }
00888
00889 if (mimetype == NULL && (encoding==PT_ENCODED || encoding==QP_ENCODED)) {
00890 mimetype = "text/plain";
00891 }
00892
00893
00894
00895
00896
00897 if (encoding != YENC_ENCODED) {
00898 fprintf (outfile, "MIME-Version: 1.0%s", eolstring);
00899 fprintf (outfile, "Content-Type: %s%s",
00900 (mimetype)?mimetype:"Application/Octet-Stream",
00901 eolstring);
00902 fprintf (outfile, "Content-Transfer-Encoding: %s%s",
00903 CTE_TYPE(encoding), eolstring);
00904 fprintf (outfile, "Content-Disposition: attachment; filename=\"%s\"%s",
00905 UUFNameFilter ((outfname)?outfname:infname), eolstring);
00906 }
00907
00908 fprintf (outfile, "%s", eolstring);
00909
00910
00911
00912
00913
00914 if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
00915 fprintf (outfile, "begin %o %s%s",
00916 (themode) ? themode : ((filemode)?filemode:0644),
00917 UUFNameFilter ((outfname)?outfname:infname), eolstring);
00918 }
00919 }
00920 if (encoding == YENC_ENCODED) {
00921 pcrc = crc32(0L, Z_NULL, 0);
00922 pcrcptr = &pcrc;
00923 if (numparts != 1) {
00924 if (progress.totsize == -1) {
00925 fprintf (outfile, "=ybegin part=%d line=128 name=%s%s",
00926 partno,
00927 UUFNameFilter ((outfname)?outfname:infname),
00928 eolstring);
00929 }
00930 else {
00931 fprintf (outfile, "=ybegin part=%d line=128 size=%ld name=%s%s",
00932 partno,
00933 progress.totsize,
00934 UUFNameFilter ((outfname)?outfname:infname),
00935 eolstring);
00936 }
00937
00938 fprintf (outfile, "=ypart begin=%ld end=%ld%s",
00939 (partno-1)*linperfile*128+1,
00940 (partno*linperfile*128) progress.totsize ?
00941 (partno*linperfile*128) : progress.totsize,
00942 eolstring);
00943 }
00944 else {
00945 if (progress.totsize == -1) {
00946 fprintf (outfile, "=ybegin line=128 name=%s%s",
00947 UUFNameFilter ((outfname)?outfname:infname),
00948 eolstring);
00949 }
00950 else {
00951 fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s",
00952 progress.totsize,
00953 UUFNameFilter ((outfname)?outfname:infname),
00954 eolstring);
00955 }
00956 }
00957 }
00958
00959
00960
00961
00962
00963 progress.partno = partno;
00964 progress.percent = 0;
00965 progress.foffset = ftell (theifile);
00966
00967 if (progress.totsize 00968 progress.fsize = -1;
00969 else if (linperfile 00970 progress.fsize = progress.totsize;
00971 else if (progress.foffset+linperfile*bpl[encoding] > progress.totsize)
00972 progress.fsize = progress.totsize - progress.foffset;
00973 else
00974 progress.fsize = linperfile*bpl[encoding];
00975
00976 progress.action = UUACT_ENCODING;
00977
00978 if ((res = UUEncodeStream (outfile, theifile, encoding, linperfile,
00979 crcptr, pcrcptr)) != UURET_OK) {
00980 if (infile==NULL) fclose (theifile);
00981 if (res != UURET_CANCEL) {
00982 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
00983 uustring (S_ERR_ENCODING),
00984 UUFNameFilter ((outfname)?outfname:infname),
00985 (res==UURET_IOERR)?strerror(uu_errno):UUstrerror (res));
00986 }
00987 progress.action = 0;
00988 return res;
00989 }
00990
00991
00992
00993
00994
00995 if (feof (theifile) &&
00996 (encoding == UU_ENCODED || encoding == XX_ENCODED)) {
00997 fprintf (outfile, "%c%s",
00998 (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0],
00999 eolstring);
01000 fprintf (outfile, "end%s", eolstring);
01001 }
01002 else if (encoding == YENC_ENCODED) {
01003 if (numparts != 1) {
01004 fprintf (outfile, "=yend size=%ld part=%d pcrc32=%08lx",
01005 (partno*linperfile*128) progress.totsize ?
01006 linperfile*128 : (progress.totsize-(partno-1)*linperfile*128),
01007 partno,
01008 pcrc);
01009 }
01010 else {
01011 fprintf (outfile, "=yend size=%ld",
01012 progress.totsize);
01013 }
01014 if (feof (theifile))
01015 fprintf (outfile, " crc32=%08lx", *crcptr);
01016 fprintf (outfile, "%s", eolstring);
01017 }
01018
01019
01020
01021
01022
01023 if (encoding != PT_ENCODED && encoding != QP_ENCODED) {
01024 fprintf (outfile, "%s", eolstring);
01025 }
01026
01027 if (infile==NULL) {
01028 if (res != UURET_OK) {
01029 progress.action = 0;
01030 fclose (theifile);
01031 return res;
01032 }
01033 if (feof (theifile)) {
01034 progress.action = 0;
01035 fclose (theifile);
01036 return UURET_OK;
01037 }
01038 return UURET_CONT;
01039 }
01040
01041
01042
01043
01044
01045 return UURET_OK;
01046 }
01047
01048
01049
01050
01051
01052 int UUEXPORT
01053 UUEncodeToStream (FILE *outfile, FILE *infile,
01054 char *infname, int encoding,
01055 char *outfname, int filemode)
01056 {
01057 struct stat finfo;
01058 FILE *theifile;
01059 int themode;
01060 int res;
01061 crc32_t crc;
01062 crc32_t *crcptr=NULL;
01063
01064 if (outfile==NULL ||
01065 (infile == NULL&&infname==NULL) ||
01066 (outfname==NULL&&infname==NULL) ||
01067 (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
01068 encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) {
01069 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01070 uustring (S_PARM_CHECK), "UUEncodeToStream()");
01071 return UURET_ILLVAL;
01072 }
01073
01074 progress.action = 0;
01075
01076 if (infile==NULL) {
01077 if (stat (infname, &finfo) == -1) {
01078 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01079 uustring (S_NOT_STAT_FILE),
01080 infname, strerror (uu_errno=errno));
01081 return UURET_IOERR;
01082 }
01083 if ((theifile = fopen (infname, "rb")) == NULL) {
01084 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01085 uustring (S_NOT_OPEN_FILE),
01086 infname, strerror (uu_errno=errno));
01087 return UURET_IOERR;
01088 }
01089 themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777);
01090 progress.fsize = (long) finfo.st_size;
01091 }
01092 else {
01093 if (fstat (fileno (infile), &finfo) == -1) {
01094
01095 themode = 0644;
01096 progress.fsize = -1;
01097 }
01098 else {
01099 themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777);
01100 progress.fsize = (long) finfo.st_size;
01101 }
01102 theifile = infile;
01103 }
01104
01105 if (progress.fsize 01106 progress.fsize = -1;
01107
01108 _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256);
01109
01110 progress.partno = 1;
01111 progress.numparts = 1;
01112 progress.percent = 0;
01113 progress.foffset = 0;
01114 progress.action = UUACT_ENCODING;
01115
01116 if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
01117 fprintf (outfile, "begin %o %s%s",
01118 (themode) ? themode : 0644,
01119 UUFNameFilter ((outfname)?outfname:infname),
01120 eolstring);
01121 }
01122 else if (encoding == YENC_ENCODED) {
01123 crc = crc32(0L, Z_NULL, 0);
01124 crcptr = &crc;
01125 if (progress.fsize == -1) {
01126 fprintf (outfile, "=ybegin line=128 name=%s%s",
01127 UUFNameFilter ((outfname)?outfname:infname),
01128 eolstring);
01129 }
01130 else {
01131 fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s",
01132 progress.fsize,
01133 UUFNameFilter ((outfname)?outfname:infname),
01134 eolstring);
01135 }
01136 }
01137
01138 if ((res = UUEncodeStream (outfile, theifile, encoding, 0, crcptr, NULL)) != UURET_OK) {
01139 if (res != UURET_CANCEL) {
01140 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01141 uustring (S_ERR_ENCODING),
01142 UUFNameFilter ((infname)?infname:outfname),
01143 (res==UURET_IOERR)?strerror(uu_errno):UUstrerror (res));
01144 }
01145 progress.action = 0;
01146 return res;
01147 }
01148
01149 if (encoding == UU_ENCODED || encoding == XX_ENCODED) {
01150 fprintf (outfile, "%c%s",
01151 (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0],
01152 eolstring);
01153 fprintf (outfile, "end%s", eolstring);
01154 }
01155 else if (encoding == YENC_ENCODED) {
01156 if (progress.fsize == -1) {
01157 fprintf (outfile, "=yend crc32=%08lx%s",
01158 crc,
01159 eolstring);
01160 }
01161 else {
01162 fprintf (outfile, "=yend size=%ld crc32=%08lx%s",
01163 progress.fsize,
01164 crc,
01165 eolstring);
01166 }
01167 }
01168
01169
01170
01171
01172
01173 fprintf (outfile, "%s", eolstring);
01174
01175 if (infile==NULL) fclose (theifile);
01176 progress.action = 0;
01177
01178 return UURET_OK;
01179 }
01180
01181
01182
01183
01184
01185 int UUEXPORT
01186 UUEncodeToFile (FILE *infile, char *infname, int encoding,
01187 char *outfname, char *diskname, long linperfile)
01188 {
01189 int part, numparts, len, filemode, res;
01190 char *oname=NULL, *optr, *ptr;
01191 FILE *theifile, *outfile;
01192 struct stat finfo;
01193 crc32_t pcrc, crc;
01194 crc32_t *pcrcptr=NULL, *crcptr=NULL;
01195
01196 if ((diskname==NULL&&infname==NULL) ||
01197 (outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) ||
01198 (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
01199 encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) {
01200 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01201 uustring (S_PARM_CHECK), "UUEncodeToFile()");
01202 return UURET_ILLVAL;
01203 }
01204
01205 if (diskname) {
01206 if ((ptr = strchr (diskname, '/')) == NULL)
01207 ptr = strchr (diskname, '\\');
01208 if (ptr) {
01209 len = strlen (diskname) + ((uuencodeext)?strlen(uuencodeext):3) + 5;
01210
01211 if ((oname = malloc (len)) == NULL) {
01212 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01213 uustring (S_OUT_OF_MEMORY), len);
01214 return UURET_NOMEM;
01215 }
01216 sprintf (oname, "%s", diskname);
01217 }
01218 else {
01219 len = ((uusavepath)?strlen(uusavepath):0) + strlen (diskname)
01220 + ((uuencodeext)?strlen(uuencodeext):0) + 5;
01221
01222 if ((oname = malloc (len)) == NULL) {
01223 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01224 uustring (S_OUT_OF_MEMORY), len);
01225 return UURET_NOMEM;
01226 }
01227 sprintf (oname, "%s%s", (uusavepath)?uusavepath:"", diskname);
01228 }
01229 }
01230 else {
01231 len = ((uusavepath) ? strlen (uusavepath) : 0) +
01232 strlen(UUFNameFilter(infname)) +
01233 ((uuencodeext)?strlen(uuencodeext):0) + 5;
01234
01235 if ((oname = malloc (len)) == NULL) {
01236 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01237 uustring (S_OUT_OF_MEMORY), len);
01238 return UURET_NOMEM;
01239 }
01240 optr = UUFNameFilter (infname);
01241 sprintf (oname, "%s%s",
01242 (uusavepath)?uusavepath:"",
01243 (*optr=='.')?optr+1:optr);
01244 }
01245
01246
01247
01248
01249
01250
01251 optr = _FP_strrchr (oname, '.');
01252 if (optr==NULL || strchr (optr, '/')!=NULL || strchr (optr, '\\')!=NULL) {
01253 optr = oname + strlen (oname);
01254 *optr++ = '.';
01255 }
01256 else if (optr==oname || *(optr-1)=='/' || *(optr-1)=='\\') {
01257 optr = oname + strlen (oname);
01258 *optr++ = '.';
01259 }
01260 else
01261 optr++;
01262
01263 progress.action = 0;
01264
01265 if (infile==NULL) {
01266 if (stat (infname, &finfo) == -1) {
01267 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01268 uustring (S_NOT_STAT_FILE),
01269 infname, strerror (uu_errno=errno));
01270 _FP_free (oname);
01271 return UURET_IOERR;
01272 }
01273 if ((theifile = fopen (infname, "rb")) == NULL) {
01274 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01275 uustring (S_NOT_OPEN_FILE),
01276 infname, strerror (uu_errno=errno));
01277 _FP_free (oname);
01278 return UURET_IOERR;
01279 }
01280 if (linperfile 01281 numparts = 1;
01282 else
01283 numparts = (int) (((long)finfo.st_size + (linperfile*bpl[encoding]-1)) /
01284 (linperfile*bpl[encoding]));
01285
01286 filemode = (int) finfo.st_mode & 0777;
01287 progress.totsize = (long) finfo.st_size;
01288 }
01289 else {
01290 if (fstat (fileno (infile), &finfo) == -1) {
01291
01292 filemode = 0644;
01293 numparts = -1;
01294 progress.totsize = -1;
01295 }
01296 else {
01297 if (linperfile 01298 numparts = 1;
01299 else
01300 numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/
01301 (linperfile*bpl[encoding]));
01302
01303 filemode = (int) finfo.st_mode & 0777;
01304 progress.totsize = -1;
01305 }
01306 theifile = infile;
01307 }
01308
01309 _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256);
01310
01311 progress.totsize = (progress.totsizeprogress.totsize;
01312 progress.numparts = numparts;
01313
01314 for (part=1; !feof (theifile); part++) {
01315
01316
01317
01318 if (progress.numparts==1 && progress.totsize!=-1 && uuencodeext!=NULL)
01319 strcpy (optr, uuencodeext);
01320 else
01321 sprintf (optr, "%03d", part);
01322
01323
01324
01325
01326
01327 if (!uu_overwrite) {
01328 if (stat (oname, &finfo) == 0) {
01329 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01330 uustring (S_TARGET_EXISTS), oname);
01331 if (infile==NULL) fclose (theifile);
01332 progress.action = 0;
01333 free (oname);
01334 return UURET_EXISTS;
01335 }
01336 }
01337
01338
01339
01340
01341
01342 progress.action = 0;
01343 progress.partno = part;
01344 progress.percent = 0;
01345 progress.foffset = ftell (theifile);
01346
01347 if (progress.totsize == -1)
01348 progress.fsize = -1;
01349 else if (linperfile 01350 progress.fsize = progress.totsize;
01351 else if (progress.foffset+linperfile*bpl[encoding] > progress.totsize)
01352 progress.fsize = progress.totsize - progress.foffset;
01353 else
01354 progress.fsize = linperfile*bpl[encoding];
01355
01356 progress.action = UUACT_ENCODING;
01357
01358 if ((outfile = fopen (oname, "w")) == NULL) {
01359 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01360 uustring (S_NOT_OPEN_TARGET),
01361 oname, strerror (uu_errno = errno));
01362 if (infile==NULL) fclose (theifile);
01363 progress.action = 0;
01364 free (oname);
01365 return UURET_IOERR;
01366 }
01367
01368 if (encoding != YENC_ENCODED) {
01369 fprintf (outfile, "%s", eolstring);
01370 fprintf (outfile, "_=_ %s", eolstring);
01371 if (numparts == -1)
01372 fprintf (outfile, "_=_ Part %03d of file %s%s",
01373 part, UUFNameFilter ((outfname)?outfname:infname),
01374 eolstring);
01375 else
01376 fprintf (outfile, "_=_ Part %03d of %03d of file %s%s",
01377 part, numparts,
01378 UUFNameFilter ((outfname)?outfname:infname),
01379 eolstring);
01380 fprintf (outfile, "_=_ %s", eolstring);
01381 fprintf (outfile, "%s", eolstring);
01382 }
01383
01384 if (part==1 && (encoding == UU_ENCODED || encoding == XX_ENCODED)) {
01385 fprintf (outfile, "begin %o %s%s",
01386 (filemode)?filemode : 0644,
01387 UUFNameFilter ((outfname)?outfname:infname),
01388 eolstring);
01389 }
01390 else if (encoding == YENC_ENCODED) {
01391 if (!crcptr) {
01392 crc = crc32(0L, Z_NULL, 0);
01393 crcptr = &crc;
01394 }
01395 pcrc = crc32(0L, Z_NULL, 0);
01396 pcrcptr = &pcrc;
01397 if (numparts != 1) {
01398 if (progress.totsize == -1) {
01399 fprintf (outfile, "=ybegin part=%d line=128 name=%s%s",
01400 part,
01401 UUFNameFilter ((outfname)?outfname:infname),
01402 eolstring);
01403 }
01404 else {
01405 fprintf (outfile, "=ybegin part=%d line=128 size=%ld name=%s%s",
01406 part,
01407 progress.totsize,
01408 UUFNameFilter ((outfname)?outfname:infname),
01409 eolstring);
01410 }
01411
01412 fprintf (outfile, "=ypart begin=%ld end=%ld%s",
01413 (part-1)*linperfile*128+1,
01414 (part*linperfile*128) progress.totsize ?
01415 (part*linperfile*128) : progress.totsize,
01416 eolstring);
01417 }
01418 else {
01419 if (progress.totsize == -1) {
01420 fprintf (outfile, "=ybegin line=128 name=%s%s",
01421 UUFNameFilter ((outfname)?outfname:infname),
01422 eolstring);
01423 }
01424 else {
01425 fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s",
01426 progress.totsize,
01427 UUFNameFilter ((outfname)?outfname:infname),
01428 eolstring);
01429 }
01430 }
01431 }
01432
01433 if ((res = UUEncodeStream (outfile, theifile,
01434 encoding, linperfile, crcptr, pcrcptr)) != UURET_OK) {
01435 if (res != UURET_CANCEL) {
01436 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01437 uustring (S_ERR_ENCODING),
01438 UUFNameFilter ((infname)?infname:outfname),
01439 (res==UURET_IOERR)?strerror(uu_errno):UUstrerror (res));
01440 }
01441 if (infile==NULL) fclose (theifile);
01442 progress.action = 0;
01443 fclose (outfile);
01444 unlink (oname);
01445 _FP_free (oname);
01446 return res;
01447 }
01448
01449 if (feof (theifile) &&
01450 (encoding == UU_ENCODED || encoding == XX_ENCODED)) {
01451 fprintf (outfile, "%c%s",
01452 (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0],
01453 eolstring);
01454 fprintf (outfile, "end%s", eolstring);
01455 }
01456 else if (encoding == YENC_ENCODED) {
01457 if (numparts != 1) {
01458 fprintf (outfile, "=yend size=%ld part=%d pcrc32=%08lx",
01459 (part*linperfile*128) progress.totsize ?
01460 linperfile*128 : (progress.totsize-(part-1)*linperfile*128),
01461 part,
01462 pcrc);
01463 }
01464 else {
01465 fprintf (outfile, "=yend size=%ld",
01466 progress.totsize);
01467 }
01468 if (feof (theifile))
01469 fprintf (outfile, " crc32=%08lx", crc);
01470 fprintf (outfile, "%s", eolstring);
01471 }
01472
01473
01474
01475
01476
01477 fprintf (outfile, "%s", eolstring);
01478 fclose (outfile);
01479 }
01480
01481 if (infile==NULL) fclose (theifile);
01482 progress.action = 0;
01483 _FP_free (oname);
01484 return UURET_OK;
01485 }
01486
01487
01488
01489
01490
01491
01492
01493 int UUEXPORT
01494 UUE_PrepSingle (FILE *outfile, FILE *infile,
01495 char *infname, int encoding,
01496 char *outfname, int filemode,
01497 char *destination, char *from,
01498 char *subject, int isemail)
01499 {
01500 return UUE_PrepSingleExt (outfile, infile,
01501 infname, encoding,
01502 outfname, filemode,
01503 destination, from,
01504 subject, NULL,
01505 isemail);
01506 }
01507
01508 int UUEXPORT
01509 UUE_PrepSingleExt (FILE *outfile, FILE *infile,
01510 char *infname, int encoding,
01511 char *outfname, int filemode,
01512 char *destination, char *from,
01513 char *subject, char *replyto,
01514 int isemail)
01515 {
01516 mimemap *miter=mimetable;
01517 char *subline, *oname;
01518 char *mimetype, *ptr;
01519 int res, len;
01520
01521 if ((outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) ||
01522 (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
01523 encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) {
01524 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01525 uustring (S_PARM_CHECK), "UUE_PrepSingle()");
01526 return UURET_ILLVAL;
01527 }
01528
01529 oname = UUFNameFilter ((outfname)?outfname:infname);
01530 len = ((subject)?strlen(subject):0) + strlen(oname) + 40;
01531
01532 if ((ptr = _FP_strrchr (oname, '.'))) {
01533 while (miter->extension && _FP_stricmp (ptr+1, miter->extension) != 0)
01534 miter++;
01535 mimetype = miter->mimetype;
01536 }
01537 else
01538 mimetype = NULL;
01539
01540 if (mimetype == NULL && (encoding == PT_ENCODED || encoding == QP_ENCODED)) {
01541 mimetype = "text/plain";
01542 }
01543
01544 if ((subline = (char *) malloc (len)) == NULL) {
01545 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01546 uustring (S_OUT_OF_MEMORY), len);
01547 return UURET_NOMEM;
01548 }
01549
01550 if (encoding == YENC_ENCODED) {
01551 if (subject)
01552 sprintf (subline, "- %s - %s (001/001)", oname, subject);
01553 else
01554 sprintf (subline, "- %s - (001/001)", oname);
01555 }
01556 else {
01557 if (subject)
01558 sprintf (subline, "%s (001/001) - [ %s ]", subject, oname);
01559 else
01560 sprintf (subline, "[ %s ] (001/001)", oname);
01561 }
01562
01563 if (from) {
01564 fprintf (outfile, "From: %s%s", from, eolstring);
01565 }
01566 if (destination) {
01567 fprintf (outfile, "%s: %s%s",
01568 (isemail)?"To":"Newsgroups",
01569 destination, eolstring);
01570 }
01571
01572 fprintf (outfile, "Subject: %s%s", subline, eolstring);
01573
01574 if (replyto) {
01575 fprintf (outfile, "Reply-To: %s%s", replyto, eolstring);
01576 }
01577
01578 if (encoding != YENC_ENCODED) {
01579 fprintf (outfile, "MIME-Version: 1.0%s", eolstring);
01580 fprintf (outfile, "Content-Type: %s; name=\"%s\"%s",
01581 (mimetype)?mimetype:"Application/Octet-Stream",
01582 UUFNameFilter ((outfname)?outfname:infname),
01583 eolstring);
01584 fprintf (outfile, "Content-Transfer-Encoding: %s%s",
01585 CTE_TYPE(encoding), eolstring);
01586 }
01587
01588 fprintf (outfile, "%s", eolstring);
01589
01590 res = UUEncodeToStream (outfile, infile, infname, encoding,
01591 outfname, filemode);
01592
01593 _FP_free (subline);
01594 return res;
01595 }
01596
01597 int UUEXPORT
01598 UUE_PrepPartial (FILE *outfile, FILE *infile,
01599 char *infname, int encoding,
01600 char *outfname, int filemode,
01601 int partno, long linperfile, long filesize,
01602 char *destination, char *from, char *subject,
01603 int isemail)
01604 {
01605 return UUE_PrepPartialExt (outfile, infile,
01606 infname, encoding,
01607 outfname, filemode,
01608 partno, linperfile, filesize,
01609 destination,
01610 from, subject, NULL,
01611 isemail);
01612 }
01613
01614 int UUEXPORT
01615 UUE_PrepPartialExt (FILE *outfile, FILE *infile,
01616 char *infname, int encoding,
01617 char *outfname, int filemode,
01618 int partno, long linperfile, long filesize,
01619 char *destination,
01620 char *from, char *subject, char *replyto,
01621 int isemail)
01622 {
01623 static int numparts, themode;
01624 static char mimeid[64];
01625 static FILE *theifile;
01626 struct stat finfo;
01627 char *subline, *oname;
01628 long thesize;
01629 int res, len;
01630 static crc32_t crc;
01631 crc32_t *crcptr=NULL;
01632
01633 if ((outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) ||
01634 (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&&
01635 encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) {
01636 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01637 uustring (S_PARM_CHECK), "UUE_PrepPartial()");
01638 return UURET_ILLVAL;
01639 }
01640
01641 oname = UUFNameFilter ((outfname)?outfname:infname);
01642 len = ((subject)?strlen(subject):0) + strlen (oname) + 40;
01643
01644
01645
01646
01647
01648 if (partno == 1) {
01649 if (infile==NULL) {
01650 if (stat (infname, &finfo) == -1) {
01651 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01652 uustring (S_NOT_STAT_FILE),
01653 infname, strerror (uu_errno=errno));
01654 return UURET_IOERR;
01655 }
01656 if ((theifile = fopen (infname, "rb")) == NULL) {
01657 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01658 uustring (S_NOT_OPEN_FILE),
01659 infname, strerror (uu_errno=errno));
01660 return UURET_IOERR;
01661 }
01662 if (linperfile 01663 numparts = 1;
01664 else
01665 numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/
01666 (linperfile*bpl[encoding]));
01667
01668 themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777);
01669 thesize = (long) finfo.st_size;
01670 }
01671 else {
01672 if (fstat (fileno (infile), &finfo) != 0) {
01673 if (filesize 01674 UUMessage (uuencode_id, __LINE__, UUMSG_WARNING,
01675 uustring (S_STAT_ONE_PART));
01676 numparts = 1;
01677 themode = (filemode)?filemode:0644;
01678 thesize = -1;
01679 }
01680 else {
01681 if (linperfile 01682 numparts = 1;
01683 else
01684 numparts = (int) ((filesize+(linperfile*bpl[encoding]-1))/
01685 (linperfile*bpl[encoding]));
01686
01687 themode = (filemode)?filemode:0644;
01688 thesize = filesize;
01689 }
01690 }
01691 else {
01692 if (linperfile 01693 numparts = 1;
01694 else
01695 numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/
01696 (linperfile*bpl[encoding]));
01697
01698 filemode = (int) finfo.st_mode & 0777;
01699 thesize = (long) finfo.st_size;
01700 }
01701 theifile = infile;
01702 }
01703
01704
01705
01706
01707
01708 if (numparts == 1) {
01709 if (infile==NULL) fclose (theifile);
01710 return UUE_PrepSingleExt (outfile, infile, infname, encoding,
01711 outfname, filemode, destination,
01712 from, subject, replyto, isemail);
01713 }
01714
01715
01716
01717
01718
01719 sprintf (mimeid, "UUDV-%ld.%ld.%s",
01720 (long) time(NULL), thesize,
01721 (strlen(oname)>16)?"oops":oname);
01722 }
01723
01724 if ((subline = (char *) malloc (len)) == NULL) {
01725 UUMessage (uuencode_id, __LINE__, UUMSG_ERROR,
01726 uustring (S_OUT_OF_MEMORY), len);
01727 if (infile==NULL) fclose (theifile);
01728 return UURET_NOMEM;
01729 }
01730
01731
01732 if (encoding == YENC_ENCODED) {
01733 if (partno == 1)
01734 crc = crc32(0L, Z_NULL, 0);
01735 crcptr = &crc;
01736 if (subject)
01737 sprintf (subline, "- %s - %s (%03d/%03d)", oname, subject,
01738 partno, numparts);
01739 else
01740 sprintf (subline, "- %s - (%03d/%03d)", oname,
01741 partno, numparts);
01742 }
01743 else {
01744 if (subject)
01745 sprintf (subline, "%s (%03d/%03d) - [ %s ]",
01746 subject, partno, numparts, oname);
01747 else
01748 sprintf (subline, "[ %s ] (%03d/%03d)",
01749 oname, partno, numparts);
01750 }
01751
01752 if (from) {
01753 fprintf (outfile, "From: %s%s", from, eolstring);
01754 }
01755
01756 if (destination) {
01757 fprintf (outfile, "%s: %s%s",
01758 (isemail)?"To":"Newsgroups",
01759 destination, eolstring);
01760 }
01761
01762 fprintf (outfile, "Subject: %s%s", subline, eolstring);
01763
01764 if (replyto) {
01765 fprintf (outfile, "Reply-To: %s%s", replyto, eolstring);
01766 }
01767
01768 if (encoding != YENC_ENCODED) {
01769 fprintf (outfile, "MIME-Version: 1.0%s", eolstring);
01770 fprintf (outfile, "Content-Type: Message/Partial; number=%d; total=%d;%s",
01771 partno, numparts, eolstring);
01772 fprintf (outfile, "\tid=\"%s\"%s",
01773 mimeid, eolstring);
01774 }
01775
01776 fprintf (outfile, "%s", eolstring);
01777
01778 res = UUEncodePartial (outfile, theifile,
01779 infname, encoding,
01780 (outfname)?outfname:infname, NULL,
01781 themode, partno, linperfile, crcptr);
01782
01783 _FP_free (subline);
01784
01785 if (infile==NULL) {
01786 if (res != UURET_OK) {
01787 fclose (theifile);
01788 return res;
01789 }
01790 if (feof (theifile)) {
01791 fclose (theifile);
01792 return UURET_OK;
01793 }
01794 return UURET_CONT;
01795 }
01796
01797 return res;
01798 }