ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-UUlib/uulib/uunconc.c
(Generate patch)

Comparing Convert-UUlib/uulib/uunconc.c (file contents):
Revision 1.3.2.5 by root, Sun Apr 18 19:55:46 2004 UTC vs.
Revision 1.33 by root, Sat Sep 24 17:40:45 2022 UTC

35#include <os2.h> 35#include <os2.h>
36#endif 36#endif
37 37
38#include <stdio.h> 38#include <stdio.h>
39#include <ctype.h> 39#include <ctype.h>
40
41#ifdef STDC_HEADERS
42#include <stdlib.h> 40#include <stdlib.h>
43#include <string.h> 41#include <string.h>
44#endif 42#include <errno.h>
43
45#ifdef HAVE_UNISTD_H 44#ifdef HAVE_UNISTD_H
46#include <unistd.h> 45#include <unistd.h>
47#endif
48#ifdef HAVE_ERRNO_H
49#include <errno.h>
50#endif 46#endif
51 47
52#include <crc32.h> 48#include <crc32.h>
53#include <uudeview.h> 49#include <uudeview.h>
54#include <uuint.h> 50#include <uuint.h>
55#include <fptools.h> 51#include <fptools.h>
56#include <uustring.h> 52#include <uustring.h>
57
58char * uunconc_id = "$Id: uunconc.c,v 1.3.2.5 2004/04/18 19:55:46 root Exp $";
59 53
60/* for braindead systems */ 54/* for braindead systems */
61#ifndef SEEK_SET 55#ifndef SEEK_SET
62#ifdef L_BEGIN 56#ifdef L_BEGIN
63#define SEEK_SET L_BEGIN 57#define SEEK_SET L_BEGIN
117 111
118/* 112/*
119 * To prevent warnings when using a char as index into an array 113 * To prevent warnings when using a char as index into an array
120 */ 114 */
121 115
122#define ACAST(s) ((int)(unsigned char)(s)) 116#define ACAST(s) ((int)(uchar)(s))
123 117
124/* 118/*
125 * Initialize decoding tables 119 * Initialize decoding tables
126 */ 120 */
127 121
138 B64xlat = (int *) uunconc_B64xlat; 132 B64xlat = (int *) uunconc_B64xlat;
139 XXxlat = (int *) uunconc_XXxlat; 133 XXxlat = (int *) uunconc_XXxlat;
140 BHxlat = (int *) uunconc_BHxlat; 134 BHxlat = (int *) uunconc_BHxlat;
141 135
142 save[0] = uunconc_save; 136 save[0] = uunconc_save;
143 save[1] = uunconc_save + 256; 137 save[1] = uunconc_save + 1200;
144 save[2] = uunconc_save + 512; 138 save[2] = uunconc_save + 2400;
145 139
146 /* prepare decoding translation table */ 140 /* prepare decoding translation table */
147 for(i = 0; i < 256; i++) 141 for(i = 0; i < 256; i++)
148 UUxlat[i] = B64xlat[i] = XXxlat[i] = BHxlat[i] = -1; 142 UUxlat[i] = B64xlat[i] = XXxlat[i] = BHxlat[i] = -1;
149 143
185 * Determines whether Netscape may have broken up a data line (by 179 * Determines whether Netscape may have broken up a data line (by
186 * inserting a newline). This only seems to happen after <a in a 180 * inserting a newline). This only seems to happen after <a in a
187 * href statement 181 * href statement
188 */ 182 */
189 183
190int 184static int
191UUBrokenByNetscape (char *string) 185UUBrokenByNetscape (char *string)
192{ 186{
193 char *ptr; 187 char *ptr;
194 int len; 188 int len;
195 189
196 if (string==NULL || (len=strlen(string))<3) 190 if (string==NULL || (len=strlen(string))<3)
197 return 0; 191 return 0;
198 192
199 if ((ptr = _FP_stristr (string, "<a href=")) != NULL) { 193 if ((ptr = FP_stristr (string, "<a href=")) != NULL) {
200 if (_FP_stristr (string, "</a>") > ptr) 194 if (FP_stristr (string, "</a>") > ptr)
201 return 2; 195 return 2;
202 } 196 }
203 197
204 ptr = string + len; 198 ptr = string + len;
205 199
206 while (len && (*(ptr-1)=='\015' || *(ptr-1)=='\012')) {
207 ptr--; len--;
208 }
209 if (len<3) return 0; 200 if (len<3) return 0;
210 if (*--ptr == ' ') ptr--; 201 if (*--ptr == ' ') ptr--;
211 ptr--; 202 ptr--;
212 203
213 if (_FP_strnicmp (ptr, "<a", 2) == 0) 204 if (FP_strnicmp (ptr, "<a", 2) == 0)
214 return 1; 205 return 1;
215 206
216 return 0; 207 return 0;
217} 208}
218 209
219/* 210/*
220 * Try to repair a Netscape-corrupted line of data. 211 * Try to repair a Netscape-corrupted line of data.
221 * This must only be called on corrupted lines, since non-Netscape 212 * This must only be called on corrupted lines, since non-Netscape
222 * data may even _get_ corrupted by this procedure. 213 * data may even _get_ corrupted by this procedure.
223 * 214 *
224 * Some checks are included multiply to speed up the procedure. For 215 * Some checks are included multiply to speed up the procedure. For
225 * example: (*p1!='<' || strnicmp(p1,"</a>",4)). If the first expression 216 * example: (*p1!='<' || strnicmp(p1,"</a>",4)). If the first expression
226 * becomes true, the costly function isn't called :-) 217 * becomes true, the costly function isn't called :-)
227 * 218 *
228 * Since '<', '>', '&' might even be replaced by their html equivalents 219 * Since '<', '>', '&' might even be replaced by their html equivalents
229 * in href strings, I'm now using two passes, the first one for &amp; + co, 220 * in href strings, I'm now using two passes, the first one for &amp; + co,
230 * the second one for hrefs. 221 * the second one for hrefs.
231 */ 222 */
232 223
233int 224static int
234UUNetscapeCollapse (char *string) 225UUNetscapeCollapse (char *string)
235{ 226{
236 char *p1=string, *p2=string; 227 char *p1=string, *p2=string;
237 int res = 0; 228 int res = 0;
238 229
242 /* 233 /*
243 * First pass 234 * First pass
244 */ 235 */
245 while (*p1) { 236 while (*p1) {
246 if (*p1 == '&') { 237 if (*p1 == '&') {
247 if (_FP_strnicmp (p1, "&amp;", 5) == 0) { p1+=5; *p2++='&'; res=1; } 238 if (FP_strnicmp (p1, "&amp;", 5) == 0) { p1+=5; *p2++='&'; res=1; }
248 else if (_FP_strnicmp (p1, "&lt;", 4) == 0) { p1+=4; *p2++='<'; res=1; } 239 else if (FP_strnicmp (p1, "&lt;", 4) == 0) { p1+=4; *p2++='<'; res=1; }
249 else if (_FP_strnicmp (p1, "&gt;", 4) == 0) { p1+=4; *p2++='>'; res=1; } 240 else if (FP_strnicmp (p1, "&gt;", 4) == 0) { p1+=4; *p2++='>'; res=1; }
250 else *p2++ = *p1++; 241 else *p2++ = *p1++;
242 res = 1;
251 } 243 }
252 else *p2++ = *p1++; 244 else *p2++ = *p1++;
253 } 245 }
254 *p2 = '\0'; 246 *p2 = '\0';
255 /* 247 /*
257 */ 249 */
258 p1 = p2 = string; 250 p1 = p2 = string;
259 251
260 while (*p1) { 252 while (*p1) {
261 if (*p1 == '<') { 253 if (*p1 == '<') {
262 if ((_FP_strnicmp (p1, "<ahref=", 7) == 0 || 254 if ((FP_strnicmp (p1, "<ahref=", 7) == 0 ||
263 _FP_strnicmp (p1, "<a href=",8) == 0) && 255 FP_strnicmp (p1, "<a href=",8) == 0) &&
264 (_FP_strstr (p1, "</a>") != 0 || _FP_strstr (p1, "</A>") != 0)) { 256 (FP_strstr (p1, "</a>") != 0 || FP_strstr (p1, "</A>") != 0)) {
265 while (*p1 && *p1!='>') p1++; 257 while (*p1 && *p1!='>') p1++;
266 if (*p1=='\0' || *(p1+1)!='<') return 0; 258 if (*p1=='\0' || *(p1+1)!='<') return 0;
267 p1++; 259 p1++;
268 while (*p1 && (*p1!='<' || _FP_strnicmp(p1,"</a>",4)!=0)) { 260 while (*p1 && (*p1!='<' || FP_strnicmp(p1,"</a>",4)!=0)) {
269 *p2++ = *p1++; 261 *p2++ = *p1++;
270 } 262 }
271 if (_FP_strnicmp(p1,"</a>",4) != 0) 263 if (FP_strnicmp(p1,"</a>",4) != 0)
272 return 0; 264 return 0;
273 p1+=4; 265 p1+=4;
274 res=1; 266 res=1;
275 } 267 }
276 else 268 else
294 286
295int 287int
296UUValidData (char *ptr, int encoding, int *bhflag) 288UUValidData (char *ptr, int encoding, int *bhflag)
297{ 289{
298 int i=0, j, len=0, suspicious=0, flag=0; 290 int i=0, j, len=0, suspicious=0, flag=0;
299 char *s = ptr; 291 signed char *s = ptr;
300 292
301 if ((s == NULL) || (*s == '\0')) { 293 if ((s == NULL) || (*s == '\0')) {
302 return 0; /* bad string */ 294 return 0; /* bad string */
303 } 295 }
304 296
305 while (*s && *s!='\012' && *s!='\015') { 297 if (encoding == YENC_ENCODED)
306 s++; 298 return YENC_ENCODED;
307 len++;
308 i++;
309 }
310 299
311 if (i == 0) 300 i = strlen (s);
312 return 0;
313 301
314 switch (encoding) { 302 switch (encoding) {
315 case UU_ENCODED: 303 case UU_ENCODED:
316 goto _t_UU; 304 goto _t_UU;
317 case XX_ENCODED: 305 case XX_ENCODED:
318 goto _t_XX; 306 goto _t_XX;
319 case B64ENCODED: 307 case B64ENCODED:
320 goto _t_B64; 308 goto _t_B64;
321 case BH_ENCODED: 309 case BH_ENCODED:
322 goto _t_Binhex; 310 goto _t_Binhex;
323 case YENC_ENCODED:
324 return YENC_ENCODED;
325 } 311 }
326 312
327 _t_Binhex: /* Binhex Test */ 313 _t_Binhex: /* Binhex Test */
328 len = i; s = ptr; 314 len = i; s = ptr;
329 315
542 while (vflag == 0 && nflag && safety--) { 528 while (vflag == 0 && nflag && safety--) {
543 if (nflag == 1) { /* need next line to repair */ 529 if (nflag == 1) { /* need next line to repair */
544 if (strlen (line) > 250) 530 if (strlen (line) > 250)
545 break; 531 break;
546 ptr = line + strlen (line); 532 ptr = line + strlen (line);
547 while (ptr>line && (*(ptr-1)=='\015' || *(ptr-1)=='\012'))
548 ptr--;
549 if (_FP_fgets (ptr, 255-(ptr-line), datei) == NULL) 533 if (FP_fgets (ptr, 299-(ptr-line), datei) == NULL)
550 break; 534 break;
551 } 535 }
552 else { /* don't need next line to repair */ 536 else { /* don't need next line to repair */
553 } 537 }
554 if (UUNetscapeCollapse (line)) { 538 if (UUNetscapeCollapse (line)) {
576 * it! 560 * it!
577 */ 561 */
578 562
579 if (vflag == 0) { 563 if (vflag == 0) {
580 ptr = line + strlen(line); 564 ptr = line + strlen(line);
581 while (ptr>line && (*(ptr-1)=='\012' || *(ptr-1)=='\015')) {
582 ptr--;
583 }
584 *ptr++ = ' '; 565 *ptr++ = ' ';
585 *ptr-- = '\0'; 566 *ptr-- = '\0';
586 if ((vflag = UUValidData (line, encoding, bhflag)) != UU_ENCODED) { 567 if ((vflag = UUValidData (line, encoding, bhflag)) != UU_ENCODED) {
587 *ptr = '\0'; 568 *ptr = '\0';
588 vflag = 0; 569 vflag = 0;
614 /* 595 /*
615 * To shut up gcc -Wall 596 * To shut up gcc -Wall
616 */ 597 */
617 z1 = z2 = z3 = z4 = 0; 598 z1 = z2 = z3 = z4 = 0;
618 599
600 if (method == YENC_ENCODED) {
601 while (*s) {
602 if (ecb_expect_false (*s == '=')) {
603 if (*++s != '\0') {
604 d[count++] = (char) ((int) *s - 64 - 42);
605 s++;
606 }
607 }
608 #if 0 /* FP_fgets never leaves CR or LF in the buffer, so skip this */
609 else if (ecb_expect_false (*s == '\n' || *s == '\r')) {
610 s++; /* ignore */
611 }
612 #endif
613 else {
614 d[count++] = (char) ((int) *s++ - 42);
615 }
616 }
617 }
619 if (method == UU_ENCODED || method == XX_ENCODED) { 618 else if (method == UU_ENCODED || method == XX_ENCODED) {
620 if (method == UU_ENCODED) 619 if (method == UU_ENCODED)
621 table = UUxlat; 620 table = UUxlat;
622 else 621 else
623 table = XXxlat; 622 table = XXxlat;
624 623
630 cc = table[ACAST(*s++)]; 629 cc = table[ACAST(*s++)];
631 c |= (cc >> 4); 630 c |= (cc >> 4);
632 631
633 if(i-- > 0) 632 if(i-- > 0)
634 d[count++] = c; 633 d[count++] = c;
635 634
636 cc <<= 4; 635 cc <<= 4;
637 c = table[ACAST(*s++)]; 636 c = table[ACAST(*s++)];
638 cc |= (c >> 2); 637 cc |= (c >> 2);
639 638
640 if(i-- > 0) 639 if(i-- > 0)
641 d[count++] = cc; 640 d[count++] = cc;
642 641
643 c <<= 6; 642 c <<= 6;
644 c |= table[ACAST(*s++)]; 643 c |= table[ACAST(*s++)];
645 644
646 if(i-- > 0) 645 if(i-- > 0)
647 d[count++] = c; 646 d[count++] = c;
648 647
649 j -= 4; 648 j -= 4;
650 } 649 }
651 } 650 }
652 else if (method == B64ENCODED) { 651 else if (method == B64ENCODED) {
653 if (leftover) { 652 if (leftover) {
654 strcpy (uuncdl_fulline+leftover, s); 653 strcpy (uuncdl_fulline + leftover, s);
654
655 leftover = 0; 655 leftover = 0;
656 s = uuncdl_fulline; 656 s = uuncdl_fulline;
657 } 657 }
658 658
659 while ((z1 = B64xlat[ACAST(*s)]) != -1) { 659 while ((z1 = B64xlat[ACAST(*s)]) != -1) {
679 while (B64xlat[ACAST(*s)] != -1) 679 while (B64xlat[ACAST(*s)] != -1)
680 uuncdl_fulline[leftover++] = *s++; 680 uuncdl_fulline[leftover++] = *s++;
681 } 681 }
682 else if (method == BH_ENCODED) { 682 else if (method == BH_ENCODED) {
683 if (leftover) { 683 if (leftover) {
684 strcpy (uuncdl_fulline+leftover, s); 684 strcpy (uuncdl_fulline + leftover, s);
685
685 leftover = 0; 686 leftover = 0;
686 s = uuncdl_fulline; 687 s = uuncdl_fulline;
687 } 688 }
688 else if (*s == ':') 689 else if (*s == ':')
689 s++; 690 s++;
709 s+=3; 710 s+=3;
710 } 711 }
711 while (BHxlat[ACAST(*s)] != -1) 712 while (BHxlat[ACAST(*s)] != -1)
712 uuncdl_fulline[leftover++] = *s++; 713 uuncdl_fulline[leftover++] = *s++;
713 } 714 }
714 else if (method == YENC_ENCODED) {
715 while (*s) {
716 if (*s == '=') {
717 if (*++s != '\0') {
718 d[count++] = (char) ((int) *s - 64 - 42);
719 s++;
720 }
721 }
722 else if (*s == '\n' || *s == '\r') {
723 s++; /* ignore */
724 }
725 else {
726 d[count++] = (char) ((int) *s++ - 42);
727 }
728 }
729 }
730 715
731 return count; 716 return count;
732} 717}
733 718
734/* 719/*
735 * ``Decode'' Quoted-Printable text 720 * ``Decode'' Quoted-Printable text
736 */ 721 */
737 722
738int 723static int
739UUDecodeQP (FILE *datain, FILE *dataout, int *state, 724UUDecodeQP (FILE *datain, FILE *dataout, int *state,
740 long maxpos, int method, int flags, 725 long maxpos, int method, int flags,
741 char *boundary) 726 char *boundary)
742{ 727{
743 char *line=uugen_inbuffer, *p1, *p2; 728 char *line=uugen_inbuffer, *p1, *p2;
744 int val; 729 int val;
745 730
746 uulboundary = -1; 731 uulboundary = -1;
747 732
748 while (!feof (datain) && 733 while (!FP_feof (datain) &&
749 (ftell(datain)<maxpos || flags&FL_TOEND || 734 (ftell(datain)<maxpos || flags&FL_TOEND ||
750 (!(flags&FL_PROPER) && uu_fast_scanning))) { 735 (!(flags&FL_PROPER) && uu_fast_scanning))) {
751 if (_FP_fgets (line, 255, datain) == NULL) 736 if (FP_fgets (line, 1023, datain) == NULL)
752 break; 737 break;
753 if (ferror (datain)) { 738 if (ferror (datain)) {
754 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 739 UUMessage (UUMSG_ERROR, uustring (S_SOURCE_READ_ERR), strerror (uu_errno = errno));
755 uustring (S_SOURCE_READ_ERR),
756 strerror (uu_errno = errno));
757 return UURET_IOERR; 740 return UURET_IOERR;
758 } 741 }
759 line[255] = '\0'; 742 line[255] = '\0';
760 743
761 if (boundary && line[0]=='-' && line[1]=='-' && 744 if (boundary && line[0]=='-' && line[1]=='-' &&
766 uulboundary = 0; 749 uulboundary = 0;
767 return UURET_OK; 750 return UURET_OK;
768 } 751 }
769 752
770 if (UUBUSYPOLL(ftell(datain)-progress.foffset,progress.fsize)) { 753 if (UUBUSYPOLL(ftell(datain)-progress.foffset,progress.fsize)) {
771 UUMessage (uunconc_id, __LINE__, UUMSG_NOTE, 754 UUMessage (UUMSG_NOTE, uustring (S_DECODE_CANCEL));
772 uustring (S_DECODE_CANCEL));
773 return UURET_CANCEL; 755 return UURET_CANCEL;
774 } 756 }
775 757
776 p1 = p2 = line; 758 p1 = p2 = line;
777 759
790 772
791 fputc (val, dataout); 773 fputc (val, dataout);
792 p2 += 2; 774 p2 += 2;
793 p1 = p2; 775 p1 = p2;
794 } 776 }
795 else if (*p2 == '\012' || *(p2+1) == '\015') { 777 else if (!*p2) {
796 /* soft line break */ 778 /* soft line break */
797 *p2 = '\0'; 779 goto skip_lbr;
798 break; 780 break;
799 } 781 }
800 else { 782 else {
801 /* huh? */ 783 /* huh? */
802 fputc ('=', dataout); 784 fputc ('=', dataout);
806 * p2 points to a nullbyte right after the CR/LF/CRLF 788 * p2 points to a nullbyte right after the CR/LF/CRLF
807 */ 789 */
808 val = 0; 790 val = 0;
809 while (p2>p1 && isspace (*(p2-1))) { 791 while (p2>p1 && isspace (*(p2-1))) {
810 if (*(p2-1) == '\012' || *(p2-1) == '\015') 792 if (*(p2-1) == '\012' || *(p2-1) == '\015')
811 val = 1; 793 val = 1;
812 p2--; 794 p2--;
813 } 795 }
814 *p2 = '\0'; 796 *p2 = '\0';
815 797
816 /* 798 /*
817 * If the part ends directly after this line, the data does not end 799 * If the part ends directly after this line, the data does not end
818 * with a linebreak. Or, as the docs put it, "the CRLF preceding the 800 * with a linebreak. Or, as the docs put it, "the CRLF preceding the
819 * encapsulation line is conceptually attached to the boundary. 801 * encapsulation line is conceptually attached to the boundary.
820 * So if the part ends here, don't print a line break" 802 * So if the part ends here, don't print a line break"
821 */ 803 */
804 /* something is broken here now, but it was broken before */
822 if (val && (!feof (datain) && 805 if (!FP_feof (datain) &&
823 (ftell(datain)<maxpos || flags&FL_TOEND || 806 (ftell(datain)<maxpos || flags&FL_TOEND ||
824 (!(flags&FL_PROPER) && uu_fast_scanning)))) 807 (!(flags&FL_PROPER) && uu_fast_scanning)))
825 fprintf (dataout, "%s\n", p1); 808 fprintf (dataout, "%s\n", p1);
826 else 809 else
827 fprintf (dataout, "%s", p1); 810 fprintf (dataout, "%s", p1);
811
812 skip_lbr: ;
828 } 813 }
829 return UURET_OK; 814 return UURET_OK;
830} 815}
831 816
832/* 817/*
833 * ``Decode'' plain text. Our job is to properly handle the EOL sequence 818 * ``Decode'' plain text. Our job is to properly handle the EOL sequence
834 */ 819 */
835 820
836int 821static int
837UUDecodePT (FILE *datain, FILE *dataout, int *state, 822UUDecodePT (FILE *datain, FILE *dataout, int *state,
838 long maxpos, int method, int flags, 823 long maxpos, int method, int flags,
839 char *boundary) 824 char *boundary)
840{ 825{
841 char *line=uugen_inbuffer, *ptr; 826 char *line=uugen_inbuffer, *ptr;
842 827
843 uulboundary = -1; 828 uulboundary = -1;
844 829
845 while (!feof (datain) && 830 while (!FP_feof (datain) &&
846 (ftell(datain)<maxpos || flags&FL_TOEND || 831 (ftell(datain)<maxpos || flags&FL_TOEND ||
847 (!(flags&FL_PROPER) && uu_fast_scanning))) { 832 (!(flags&FL_PROPER) && uu_fast_scanning))) {
848 if (_FP_fgets (line, 255, datain) == NULL) 833 if (FP_fgets (line, 1023, datain) == NULL)
849 break; 834 break;
850 if (ferror (datain)) { 835 if (ferror (datain)) {
851 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 836 UUMessage (UUMSG_ERROR, uustring (S_SOURCE_READ_ERR), strerror (uu_errno = errno));
852 uustring (S_SOURCE_READ_ERR),
853 strerror (uu_errno = errno));
854 return UURET_IOERR; 837 return UURET_IOERR;
855 } 838 }
856 line[255] = '\0'; 839 line[255] = '\0';
857 840
858 if (boundary && line[0]=='-' && line[1]=='-' && 841 if (boundary && line[0]=='-' && line[1]=='-' &&
863 uulboundary = 0; 846 uulboundary = 0;
864 return UURET_OK; 847 return UURET_OK;
865 } 848 }
866 849
867 if (UUBUSYPOLL(ftell(datain)-progress.foffset,progress.fsize)) { 850 if (UUBUSYPOLL(ftell(datain)-progress.foffset,progress.fsize)) {
868 UUMessage (uunconc_id, __LINE__, UUMSG_NOTE, 851 UUMessage (UUMSG_NOTE, uustring (S_DECODE_CANCEL));
869 uustring (S_DECODE_CANCEL));
870 return UURET_CANCEL; 852 return UURET_CANCEL;
871 } 853 }
872 854
873 ptr = line + strlen (line); 855 ptr = line + strlen (line);
874
875 while (ptr>line && (*(ptr-1) == '\012' || *(ptr-1) == '\015'))
876 ptr--;
877
878 856
879 /* 857 /*
880 * If the part ends directly after this line, the data does not end 858 * If the part ends directly after this line, the data does not end
881 * with a linebreak. Or, as the docs put it, "the CRLF preceding the 859 * with a linebreak. Or, as the docs put it, "the CRLF preceding the
882 * encapsulation line is conceptually attached to the boundary. 860 * encapsulation line is conceptually attached to the boundary.
883 * So if the part ends here, don't print a line break" 861 * So if the part ends here, don't print a line break"
884 */ 862 */
885 if ((*ptr == '\012' || *ptr == '\015') &&
886 (ftell(datain)<maxpos || flags&FL_TOEND || flags&FL_PARTIAL || 863 if ((ftell(datain)<maxpos || flags&FL_TOEND || flags&FL_PARTIAL ||
887 !boundary || (!(flags&FL_PROPER) && uu_fast_scanning))) { 864 !boundary || (!(flags&FL_PROPER) && uu_fast_scanning))) {
888 *ptr = '\0'; 865 *ptr = '\0';
889 fprintf (dataout, "%s\n", line); 866 fprintf (dataout, "%s\n", line);
890 } 867 }
891 else { 868 else {
940 d[count] = (isdigit (*(s+1)) ? (*(s+1)-'0') : (tolower (*(s+1))-'a'+10)) << 4; 917 d[count] = (isdigit (*(s+1)) ? (*(s+1)-'0') : (tolower (*(s+1))-'a'+10)) << 4;
941 d[count] |= (isdigit (*(s+2)) ? (*(s+2)-'0') : (tolower (*(s+2))-'a'+10)); 918 d[count] |= (isdigit (*(s+2)) ? (*(s+2)-'0') : (tolower (*(s+2))-'a'+10));
942 count++; 919 count++;
943 s+=3; 920 s+=3;
944 } 921 }
945 else if (*(s+1) == '\012' || *(s+1) == '\015') { 922 else if (!s[1]) {
946 s+=2; 923 d[count++] = '\012';
947 } 924 }
948 else { 925 else {
949 d[count++] = *s++; 926 d[count++] = *s++;
950 } 927 }
951 } 928 }
962int 939int
963UUDecodePart (FILE *datain, FILE *dataout, int *state, 940UUDecodePart (FILE *datain, FILE *dataout, int *state,
964 long maxpos, int method, int flags, 941 long maxpos, int method, int flags,
965 char *boundary) 942 char *boundary)
966{ 943{
967 char *line=uugen_fnbuffer, *oline=uuncdp_oline; 944 char *line, *oline=uuncdp_oline;
968 int warning=0, vlc=0, lc[2], hadct=0; 945 int warning=0, vlc=0, lc[2], hadct=0;
969 int tc=0, tf=0, vflag, haddata=0, haddh=0; 946 int tc=0, tf=0, vflag, haddata=0, haddh=0;
970 long yefilesize=0, yepartends=0; 947 long yefilesize=0, yepartends=0, yenotlastpart=0;
971 crc32_t yepartcrc=crc32(0L, Z_NULL, 0); 948 crc32_t yepartcrc=CRC32_INIT;
972 static crc32_t yefilecrc=0; 949 static crc32_t yefilecrc;
973 static int bhflag=0; 950 static int bhflag=0;
974 size_t count=0; 951 size_t count=0;
975 size_t yepartsize=0; 952 size_t yepartsize=0;
976 char *ptr; 953 char *ptr;
977 954
978 if (datain == NULL || dataout == NULL) { 955 if (datain == NULL || dataout == NULL) {
979 yefilecrc = crc32(0L, Z_NULL, 0); 956 yefilecrc = CRC32_INIT;
980 bhflag = 0; 957 bhflag = 0;
981 return UURET_OK; 958 return UURET_OK;
982 } 959 }
983 960
984 /* 961 /*
999 976
1000 if (method == YENC_ENCODED) { 977 if (method == YENC_ENCODED) {
1001 *state = BEGIN; 978 *state = BEGIN;
1002 } 979 }
1003 980
1004 while (!feof (datain) && *state != DONE && 981 while (!FP_feof (datain) && *state != DONE &&
1005 (ftell(datain)<maxpos || flags&FL_TOEND || maxpos==-1 || 982 (ftell(datain)<maxpos || flags&FL_TOEND || maxpos==-1 ||
1006 (!(flags&FL_PROPER) && uu_fast_scanning))) { 983 (!(flags&FL_PROPER) && uu_fast_scanning))) {
1007 if (_FP_fgets (line, 255, datain) == NULL) 984 if (FP_fgets ((line = uugen_fnbuffer), 1200 - 5, datain) == NULL)
1008 break; 985 break;
1009 986
987 /* optionally skip .. */
988 if (*line == '.' && uu_dotdot)
989 line++;
990
1010 if (ferror (datain)) { 991 if (ferror (datain)) {
1011 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 992 UUMessage (UUMSG_ERROR, uustring (S_SOURCE_READ_ERR), strerror (uu_errno = errno));
1012 uustring (S_SOURCE_READ_ERR),
1013 strerror (uu_errno = errno));
1014 return UURET_IOERR; 993 return UURET_IOERR;
1015 } 994 }
1016 995
1017 if (line[0]=='\015' || line[0]=='\012') { /* Empty line? */ 996 if (!*line) { /* Empty line? */
1018 if (*state == DATA && 997 if (*state == DATA &&
1019 (method == UU_ENCODED || method == XX_ENCODED)) 998 (method == UU_ENCODED || method == XX_ENCODED))
1020 *state = END; 999 *state = END;
1021 1000
1022 /* 1001 /*
1029 if (vlc > 5) 1008 if (vlc > 5)
1030 tf = tc = 0; 1009 tf = tc = 0;
1031 vlc = 0; 1010 vlc = 0;
1032 continue; 1011 continue;
1033 } 1012 }
1034 1013
1035 /* 1014 /*
1036 * Busy Polls 1015 * Busy Polls
1037 */ 1016 */
1038 1017
1039 if (UUBUSYPOLL(ftell(datain)-progress.foffset,progress.fsize)) { 1018 if (UUBUSYPOLL(ftell(datain)-progress.foffset,progress.fsize)) {
1040 UUMessage (uunconc_id, __LINE__, UUMSG_NOTE, 1019 UUMessage (UUMSG_NOTE, uustring (S_DECODE_CANCEL));
1041 uustring (S_DECODE_CANCEL));
1042 return UURET_CANCEL; 1020 return UURET_CANCEL;
1043 } 1021 }
1044 1022
1045 /* 1023 /*
1046 * try to make sense of data 1024 * try to make sense of data
1047 */ 1025 */
1048 1026
1049 line[255] = '\0'; /* For Safety of string functions */ 1027 line[1200 - 1] = '\0'; /* For Safety of string functions */
1050 count = 0; 1028 count = 0;
1051 1029
1052 if (boundary && line[0]=='-' && line[1]=='-' && 1030 if (boundary && line[0]=='-' && line[1]=='-' &&
1053 strncmp (line+2, boundary, strlen (boundary)) == 0) { 1031 strncmp (line+2, boundary, strlen (boundary)) == 0) {
1054 if (line[strlen(boundary)+2]=='-') 1032 if (line[strlen(boundary)+2]=='-')
1055 uulboundary = 1; 1033 uulboundary = 1;
1062 * Use this pseudo-handling only if !FL_PROPER 1040 * Use this pseudo-handling only if !FL_PROPER
1063 */ 1041 */
1064 1042
1065 if ((flags&FL_PROPER) == 0) { 1043 if ((flags&FL_PROPER) == 0) {
1066 if (strncmp (line, "BEGIN", 5) == 0 && 1044 if (strncmp (line, "BEGIN", 5) == 0 &&
1067 _FP_strstr (line, "CUT HERE") && !tf) { /* I hate these lines */ 1045 FP_strstr (line, "CUT HERE") && !tf) { /* I hate these lines */
1068 tc = tf = vlc = 0; 1046 tc = tf = vlc = 0;
1069 continue; 1047 continue;
1070 } 1048 }
1071 /* MIME body boundary */ 1049 /* MIME body boundary */
1072 if (line[0] == '-' && line[1] == '-' && method == B64ENCODED) { 1050 if (line[0] == '-' && line[1] == '-' && method == B64ENCODED) {
1078 } 1056 }
1079 hadct = 0; 1057 hadct = 0;
1080 haddh = 1; 1058 haddh = 1;
1081 continue; 1059 continue;
1082 } 1060 }
1083 if (_FP_strnicmp (line, "Content-Type", 12) == 0) 1061 if (FP_strnicmp (line, "Content-Type", 12) == 0)
1084 hadct = 1; 1062 hadct = 1;
1085 } 1063 }
1086 1064
1087 if (*state == BEGIN) { 1065 if (*state == BEGIN) {
1088 if ((method == UU_ENCODED || method == XX_ENCODED) && 1066 if ((method == UU_ENCODED || method == XX_ENCODED) &&
1089 (strncmp (line, "begin ", 6) == 0 || 1067 (strncmp (line, "begin ", 6) == 0 ||
1090 _FP_strnicmp (line, "<pre>begin ", 11) == 0)) { /* for LYNX */ 1068 FP_strnicmp (line, "<pre>begin ", 11) == 0)) { /* for LYNX */
1091 *state = DATA; 1069 *state = DATA;
1092 continue; 1070 continue;
1093 } 1071 }
1094 else if (method == BH_ENCODED && line[0] == ':') { 1072 else if (method == BH_ENCODED && line[0] == ':') {
1095 if (UUValidData (line, BH_ENCODED, &bhflag) == BH_ENCODED) { 1073 if (UUValidData (line, BH_ENCODED, &bhflag) == BH_ENCODED) {
1099 else 1077 else
1100 continue; 1078 continue;
1101 } 1079 }
1102 else if (method == YENC_ENCODED && 1080 else if (method == YENC_ENCODED &&
1103 strncmp (line, "=ybegin ", 8) == 0 && 1081 strncmp (line, "=ybegin ", 8) == 0 &&
1104 _FP_strstr (line, " name=") != NULL) { 1082 FP_strstr (line, " name=") != NULL) {
1105 *state = DATA; 1083 *state = DATA;
1106 1084
1107 if ((ptr = _FP_strstr (line, " size=")) != NULL) { 1085 if ((ptr = FP_strstr (line, " size=")) != NULL) {
1108 ptr += 6; 1086 ptr += 6;
1109 yefilesize = atoi (ptr); 1087 yefilesize = atoi (ptr);
1110 } 1088 }
1111 else { 1089 else {
1112 yefilesize = -1; 1090 yefilesize = -1;
1113 } 1091 }
1114 1092
1115 if (_FP_strstr (line, " part=") != NULL) { 1093 if ((ptr =FP_strstr (line, " part="))) {
1094 int partno = atoi (ptr + 6);
1095
1096 if ((ptr = FP_strstr (line, " total=")))
1097 yenotlastpart = atoi (ptr + 7) != partno;
1098
1116 if (_FP_fgets (line, 255, datain) == NULL) { 1099 if (FP_fgets (line, 1200 - 5, datain) == NULL) {
1117 break; 1100 break;
1118 } 1101 }
1119 1102
1120 if ((ptr = _FP_strstr (line, " end=")) == NULL) { 1103 if ((ptr = FP_strstr (line, " end=")) == NULL) {
1121 break; 1104 break;
1122 } 1105 }
1123 1106
1124 yepartends = atoi (ptr + 5); 1107 yepartends = atoi (ptr + 5);
1125 } 1108 }
1126 tf = 1; 1109 tf = 1;
1127 continue; 1110 continue;
1128 } 1111 }
1129 else { 1112 else {
1130 continue; 1113 continue;
1131 } 1114 }
1132 1115
1133 tc = tf = vlc = 0; 1116 tc = tf = vlc = 0;
1134 lc[0] = lc[1] = 0; 1117 lc[0] = lc[1] = 0;
1135 } 1118 }
1136 else if ((*state == END) && 1119 else if ((*state == END || *state == DATA) &&
1137 (method == UU_ENCODED || method == XX_ENCODED)) { 1120 (method == UU_ENCODED || method == XX_ENCODED)) {
1138 if (strncmp (line, "end", 3) == 0) { 1121 if (strncmp (line, "end", 3) == 0) {
1139 *state = DONE; 1122 *state = DONE;
1140 break; 1123 break;
1141 } 1124 }
1142 } 1125 }
1143 1126
1144 if (*state == DATA && method == YENC_ENCODED && 1127 if (*state == DATA && method == YENC_ENCODED &&
1145 strncmp (line, "=yend ", 6) == 0) { 1128 strncmp (line, "=yend ", 6) == 0) {
1129 int lastpart = !yenotlastpart && (yepartends == 0 || yepartends >= yefilesize);
1130 yefilecrc = uu_crc32_combine(yefilecrc, yepartcrc, yepartsize);
1146 if ((ptr = _FP_strstr (line, " pcrc32=")) != NULL) { 1131 if ((ptr = FP_strstr (line, " pcrc32=")) != NULL) {
1147 crc32_t pcrc32 = strtoul (ptr + 8, NULL, 16); 1132 crc32_t pcrc32 = strtoul (ptr + 8, NULL, 16);
1148 if (pcrc32 != yepartcrc) { 1133 if (pcrc32 != yepartcrc) {
1149 UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
1150 uustring (S_PCRC_MISMATCH), progress.curfile, progress.partno); 1134 UUMessage (UUMSG_WARNING, uustring (S_PCRC_MISMATCH), progress.curfile, progress.partno);
1151 } 1135 }
1136 } else if ((ptr = FP_strstr (line, " pcrc=")) != NULL) {
1137 crc32_t pcrc32 = strtoul (ptr + 6, NULL, 16);
1138 if (pcrc32 != yepartcrc) {
1139 UUMessage (UUMSG_WARNING, uustring (S_PCRC_MISMATCH), progress.curfile, progress.partno);
1140 }
1152 } 1141 }
1153 if ((ptr = _FP_strstr (line, " crc32=")) != NULL) 1142 if (lastpart && (ptr = FP_strstr (line, " crc32=")) != NULL)
1154 { 1143 {
1155 crc32_t fcrc32 = strtoul (ptr + 7, NULL, 16); 1144 crc32_t fcrc32 = strtoul (ptr + 7, NULL, 16);
1156 if (fcrc32 != yefilecrc) { 1145 if (fcrc32 != yefilecrc) {
1157 UUMessage (uunconc_id, __LINE__, UUMSG_WARNING, 1146 UUMessage (UUMSG_WARNING, uustring (S_CRC_MISMATCH), progress.curfile);
1158 uustring (S_CRC_MISMATCH), progress.curfile);
1159 } 1147 }
1160 } 1148 }
1161 if ((ptr = _FP_strstr (line, " size=")) != NULL) 1149 if ((ptr = FP_strstr (line, " size=")) != NULL)
1162 { 1150 {
1163 size_t size = atol(ptr + 6); 1151 size_t size = atol(ptr + 6);
1164 if (size != yepartsize && yefilesize != -1) { 1152 if (size != yepartsize && yefilesize != -1) {
1165 if (size != yefilesize) 1153 if (size != yefilesize)
1166 UUMessage (uunconc_id, __LINE__, UUMSG_WARNING, 1154 UUMessage (UUMSG_WARNING,
1167 uustring (S_PSIZE_MISMATCH), progress.curfile, 1155 uustring (S_PSIZE_MISMATCH), progress.curfile,
1168 progress.partno, yepartsize, size); 1156 progress.partno, yepartsize, size);
1169 else 1157 else
1170 UUMessage (uunconc_id, __LINE__, UUMSG_WARNING, 1158 UUMessage (UUMSG_WARNING,
1171 uustring (S_SIZE_MISMATCH), progress.curfile, 1159 uustring (S_SIZE_MISMATCH), progress.curfile,
1172 yepartsize, size); 1160 yepartsize, size);
1173 } 1161 }
1174 } 1162 }
1175 if (yepartends == 0 || yepartends >= yefilesize) { 1163 if (lastpart) {
1176 *state = DONE; 1164 *state = DONE;
1177 } 1165 }
1178 break; 1166 break;
1179 } 1167 }
1180 1168
1198 1186
1199 if (vflag == method) { 1187 if (vflag == method) {
1200 if (tf) { 1188 if (tf) {
1201 count = UUDecodeLine (line, oline, method); 1189 count = UUDecodeLine (line, oline, method);
1202 if (method == YENC_ENCODED) { 1190 if (method == YENC_ENCODED) {
1203 if (yepartends)
1204 yepartcrc = crc32(yepartcrc, oline, count); 1191 yepartcrc = uu_crc32(yepartcrc, oline, count);
1205 yefilecrc = crc32(yefilecrc, oline, count);
1206 yepartsize += count; 1192 yepartsize += count;
1207 } 1193 }
1208 vlc++; lc[1]++; 1194 vlc++; lc[1]++;
1209 } 1195 }
1210 else if (tc == 3) { 1196 else if (tc == 3) {
1220 * correctly encoded data. This usually means that the 1206 * correctly encoded data. This usually means that the
1221 * file is in error 1207 * file is in error
1222 */ 1208 */
1223 1209
1224 if (lc[1] > 10 && (lc[0] >= 1 && lc[0] <= 2) && !warning) { 1210 if (lc[1] > 10 && (lc[0] >= 1 && lc[0] <= 2) && !warning) {
1225 UUMessage (uunconc_id, __LINE__, UUMSG_WARNING, 1211 UUMessage (UUMSG_WARNING, uustring (S_DATA_SUSPICIOUS));
1226 uustring (S_DATA_SUSPICIOUS));
1227 warning=1; 1212 warning=1;
1228 } 1213 }
1229 lc[0] = 0; 1214 lc[0] = 0;
1230 lc[1] = 3; 1215 lc[1] = 3;
1231 } 1216 }
1232 else { 1217 else {
1233 _FP_strncpy (save[tc++], line, 256); 1218 FP_strncpy (save[tc++], line, 1200);
1234 } 1219 }
1235 1220
1236 if (method == UU_ENCODED) 1221 if (method == UU_ENCODED)
1237 *state = (line[0] == 'M') ? DATA : END; 1222 *state = (line[0] == 'M') ? DATA : END;
1238 else if (method == XX_ENCODED) 1223 else if (method == XX_ENCODED)
1253 } 1238 }
1254 1239
1255 if (count) { 1240 if (count) {
1256 if (method == BH_ENCODED) { 1241 if (method == BH_ENCODED) {
1257 if (UUbhwrite (oline, 1, count, dataout) != count) { 1242 if (UUbhwrite (oline, 1, count, dataout) != count) {
1258 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1243 UUMessage (UUMSG_ERROR, uustring (S_WR_ERR_TEMP), strerror (uu_errno = errno));
1259 uustring (S_WR_ERR_TEMP),
1260 strerror (uu_errno = errno));
1261 return UURET_IOERR; 1244 return UURET_IOERR;
1262 } 1245 }
1263 } 1246 }
1264 else if (fwrite (oline, 1, count, dataout) != count) { 1247 else if (fwrite (oline, 1, count, dataout) != count) {
1265 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1248 UUMessage (UUMSG_ERROR, uustring (S_WR_ERR_TEMP), strerror (uu_errno = errno));
1266 uustring (S_WR_ERR_TEMP),
1267 strerror (uu_errno = errno));
1268 return UURET_IOERR; 1249 return UURET_IOERR;
1269 } 1250 }
1270 haddata++; 1251 haddata++;
1271 count = 0; 1252 count = 0;
1272 } 1253 }
1273 } 1254 }
1274 1255
1275 if (*state == DONE || 1256 if (*state == DONE ||
1276 (*state == DATA && method == B64ENCODED && 1257 (*state == DATA && method == B64ENCODED &&
1277 vflag == B64ENCODED && (flags&FL_PROPER || haddh))) { 1258 vflag == B64ENCODED && (flags&FL_PROPER || haddh))) {
1278 for (tf=0; tf<tc; tf++) 1259 for (tf=0; tf<tc; tf++)
1279 count += UUDecodeLine (save[tf], oline + count, method); 1260 count += UUDecodeLine (save[tf], oline + count, method);
1280 if (count) { 1261 if (count) {
1281 if (method == BH_ENCODED) { 1262 if (method == BH_ENCODED) {
1282 if (UUbhwrite (oline, 1, count, dataout) != count) { 1263 if (UUbhwrite (oline, 1, count, dataout) != count) {
1283 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1264 UUMessage (UUMSG_ERROR, uustring (S_WR_ERR_TEMP), strerror (uu_errno = errno));
1284 uustring (S_WR_ERR_TEMP),
1285 strerror (uu_errno = errno));
1286 return UURET_IOERR; 1265 return UURET_IOERR;
1287 } 1266 }
1288 } 1267 }
1289 else if (fwrite (oline, 1, count, dataout) != count) { 1268 else if (fwrite (oline, 1, count, dataout) != count) {
1290 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1269 UUMessage (UUMSG_ERROR, uustring (S_WR_ERR_TEMP), strerror (uu_errno = errno));
1291 uustring (S_WR_ERR_TEMP),
1292 strerror (uu_errno = errno));
1293 return UURET_IOERR; 1270 return UURET_IOERR;
1294 } 1271 }
1295 } 1272 }
1296 } 1273 }
1297 return UURET_OK; 1274 return UURET_OK;
1303 1280
1304int 1281int
1305UUDecode (uulist *data) 1282UUDecode (uulist *data)
1306{ 1283{
1307 int state=BEGIN, part=-1, res=0, hb; 1284 int state=BEGIN, part=-1, res=0, hb;
1308 long rsize, dsize, numbytes; 1285 unsigned long rsize, dsize, numbytes;
1309 FILE *datain, *dataout; 1286 FILE *datain, *dataout;
1287 void *datain_buf, *dataout_buf;
1310 unsigned char r[8]; 1288 unsigned char r[8];
1311 char *mode, *ntmp; 1289 char *mode, *ntmp;
1312 uufile *iter; 1290 uufile *iter;
1313 size_t bytes; 1291 size_t bytes;
1292#ifdef HAVE_MKSTEMP
1293 int tmpfd;
1294 const char *tmpprefix = "uuXXXXXX";
1295 char *tmpdir = NULL;
1296#endif /* HAVE_MKSTEMP */
1314 1297
1315 if (data == NULL || data->thisfile == NULL) 1298 if (data == NULL || data->thisfile == NULL)
1316 return UURET_ILLVAL; 1299 return UURET_ILLVAL;
1317 1300
1318 if (data->state & UUFILE_TMPFILE) 1301 if (data->state & UUFILE_TMPFILE)
1327 if (data->uudet == PT_ENCODED) 1310 if (data->uudet == PT_ENCODED)
1328 mode = "wt"; /* open text files in text mode */ 1311 mode = "wt"; /* open text files in text mode */
1329 else 1312 else
1330 mode = "wb"; /* otherwise in binary */ 1313 mode = "wb"; /* otherwise in binary */
1331 1314
1315#ifdef HAVE_MKSTEMP
1316 if ((getuid()==geteuid()) && (getgid()==getegid())) {
1317 tmpdir=getenv("TMPDIR");
1318 }
1319
1320 if (!tmpdir) {
1321 tmpdir = "/tmp";
1322 }
1323 data->binfile = malloc(strlen(tmpdir)+strlen(tmpprefix)+2);
1324
1325 if (!data->binfile) {
1326#else
1332 if ((data->binfile = tempnam (NULL, "uu")) == NULL) { 1327 if ((data->binfile = tmpnam (NULL)) == NULL) {
1333 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1328#endif /* HAVE_MKSTEMP */
1334 uustring (S_NO_TEMP_NAME)); 1329 UUMessage (UUMSG_ERROR, uustring (S_NO_TEMP_NAME));
1335 return UURET_NOMEM; 1330 return UURET_NOMEM;
1336 } 1331 }
1337 1332
1333#ifdef HAVE_MKSTEMP
1334 strcpy(data->binfile, tmpdir);
1335 strcat(data->binfile, "/");
1336 strcat(data->binfile, tmpprefix);
1337
1338 if ((tmpfd = mkstemp(data->binfile)) == -1 ||
1339 (dataout = fdopen(tmpfd, mode)) == NULL) {
1340#else
1338 if ((dataout = fopen (data->binfile, mode)) == NULL) { 1341 if ((dataout = fopen (data->binfile, mode)) == NULL) {
1342#endif /* HAVE_MKSTEMP */
1339 /* 1343 /*
1340 * we couldn't create a temporary file. Usually this means that TMP 1344 * we couldn't create a temporary file. Usually this means that TMP
1341 * and TEMP aren't set 1345 * and TEMP aren't set
1342 */ 1346 */
1343 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1347 UUMessage (UUMSG_ERROR, uustring (S_WR_ERR_TARGET), data->binfile, strerror (uu_errno = errno));
1344 uustring (S_WR_ERR_TARGET), 1348#ifdef HAVE_MKSTEMP
1345 data->binfile, strerror (uu_errno = errno)); 1349 if (tmpfd != -1) {
1350 unlink(data->binfile);
1351 close(tmpfd);
1352 }
1353#endif /* HAVE_MKSTEMP */
1346 _FP_free (data->binfile); 1354 FP_free (data->binfile);
1347 data->binfile = NULL; 1355 data->binfile = NULL;
1348 uu_errno = errno; 1356 uu_errno = errno;
1349 return UURET_IOERR; 1357 return UURET_IOERR;
1350 } 1358 }
1359 UUSETBUF (dataout, dataout_buf, uu_wbuf);
1360 FP_flockfile (dataout);
1361
1351 /* 1362 /*
1352 * we don't have begin lines in Base64 or plain text files. 1363 * we don't have begin lines in Base64 or plain text files.
1353 */ 1364 */
1354 if (data->uudet == B64ENCODED || data->uudet == QP_ENCODED || 1365 if (data->uudet == B64ENCODED || data->uudet == QP_ENCODED ||
1355 data->uudet == PT_ENCODED) 1366 data->uudet == PT_ENCODED)
1370 /* 1381 /*
1371 * initialize progress information 1382 * initialize progress information
1372 */ 1383 */
1373 progress.action = 0; 1384 progress.action = 0;
1374 if (data->filename != NULL) { 1385 if (data->filename != NULL) {
1375 _FP_strncpy (progress.curfile, 1386 FP_strncpy (progress.curfile,
1376 (strlen(data->filename)>255)? 1387 (strlen(data->filename)>255)?
1377 (data->filename+strlen(data->filename)-255):data->filename, 1388 (data->filename+strlen(data->filename)-255):data->filename,
1378 256); 1389 256);
1379 } 1390 }
1380 else { 1391 else {
1381 _FP_strncpy (progress.curfile, 1392 FP_strncpy (progress.curfile,
1382 (strlen(data->binfile)>255)? 1393 (strlen(data->binfile)>255)?
1383 (data->binfile+strlen(data->binfile)-255):data->binfile, 1394 (data->binfile+strlen(data->binfile)-255):data->binfile,
1384 256); 1395 256);
1385 } 1396 }
1386 progress.partno = 0; 1397 progress.partno = 0;
1392 iter = data->thisfile; 1403 iter = data->thisfile;
1393 while (iter) { 1404 while (iter) {
1394 progress.numparts = (iter->partno)?iter->partno:1; 1405 progress.numparts = (iter->partno)?iter->partno:1;
1395 iter = iter->NEXT; 1406 iter = iter->NEXT;
1396 } 1407 }
1397 1408
1398 /* 1409 /*
1399 * let's rock! 1410 * let's rock!
1400 */ 1411 */
1401 1412
1402 iter = data->thisfile; 1413 iter = data->thisfile;
1420 uugen_fnbuffer, 1)) != UURET_OK) 1431 uugen_fnbuffer, 1)) != UURET_OK)
1421 break; 1432 break;
1422 if ((datain = fopen (uugen_fnbuffer, "rb")) == NULL) { 1433 if ((datain = fopen (uugen_fnbuffer, "rb")) == NULL) {
1423 (*uu_FileCallback) (uu_FileCBArg, iter->data->sfname, 1434 (*uu_FileCallback) (uu_FileCBArg, iter->data->sfname,
1424 uugen_fnbuffer, 0); 1435 uugen_fnbuffer, 0);
1425 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1436 UUMessage (UUMSG_ERROR,
1426 uustring (S_NOT_OPEN_FILE), 1437 uustring (S_NOT_OPEN_FILE),
1427 uugen_fnbuffer, strerror (uu_errno = errno)); 1438 uugen_fnbuffer, strerror (uu_errno = errno));
1428 res = UURET_IOERR; 1439 res = UURET_IOERR;
1429 break; 1440 break;
1430 } 1441 }
1431 } 1442 }
1432 else { 1443 else {
1433 if ((datain = fopen (iter->data->sfname, "rb")) == NULL) { 1444 if ((datain = fopen (iter->data->sfname, "rb")) == NULL) {
1434 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1445 UUMessage (UUMSG_ERROR,
1435 uustring (S_NOT_OPEN_FILE), 1446 uustring (S_NOT_OPEN_FILE),
1436 iter->data->sfname, strerror (uu_errno = errno)); 1447 iter->data->sfname, strerror (uu_errno = errno));
1437 res = UURET_IOERR; 1448 res = UURET_IOERR;
1438 break; 1449 break;
1439 } 1450 }
1440 _FP_strncpy (uugen_fnbuffer, iter->data->sfname, 1024); 1451 FP_strncpy (uugen_fnbuffer, iter->data->sfname, 1024);
1441 } 1452 }
1453 UUSETBUF (datain, datain_buf, uu_rbuf);
1454 FP_flockfile (datain);
1442 1455
1443 progress.partno = part; 1456 progress.partno = part;
1444 progress.fsize = (iter->data->length)?iter->data->length:-1; 1457 progress.fsize = (iter->data->length)?iter->data->length:-1;
1445 progress.percent = 0; 1458 progress.percent = 0;
1446 progress.foffset = iter->data->startpos; 1459 progress.foffset = iter->data->startpos;
1448 fseek (datain, iter->data->startpos, SEEK_SET); 1461 fseek (datain, iter->data->startpos, SEEK_SET);
1449 res = UUDecodePart (datain, dataout, &state, 1462 res = UUDecodePart (datain, dataout, &state,
1450 iter->data->startpos+iter->data->length, 1463 iter->data->startpos+iter->data->length,
1451 data->uudet, iter->data->flags, NULL); 1464 data->uudet, iter->data->flags, NULL);
1452 fclose (datain); 1465 fclose (datain);
1466 UUCLRBUF (uu_rbuf, datain_buf);
1453 1467
1454 if (uu_FileCallback) 1468 if (uu_FileCallback)
1455 (*uu_FileCallback) (uu_FileCBArg, iter->data->sfname, uugen_fnbuffer, 0); 1469 (*uu_FileCallback) (uu_FileCBArg, iter->data->sfname, uugen_fnbuffer, 0);
1456 1470
1457 if (state == DONE || res != UURET_OK) 1471 if (state == DONE || res != UURET_OK)
1458 break; 1472 break;
1459 1473
1460 iter = iter->NEXT; 1474 iter = iter->NEXT;
1461 } 1475 }
1462 1476
1463 if (state == DATA && 1477 if (state == DATA &&
1464 (data->uudet == B64ENCODED || data->uudet == QP_ENCODED || 1478 (data->uudet == B64ENCODED || data->uudet == QP_ENCODED ||
1465 data->uudet == PT_ENCODED)) 1479 data->uudet == PT_ENCODED))
1466 state = DONE; /* assume we're done */ 1480 state = DONE; /* assume we're done */
1467 1481
1468 if (fclose (dataout)) { 1482 if (fclose (dataout)) {
1469 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1483 UUMessage (UUMSG_ERROR, uustring (S_WR_ERR_TEMP), strerror (uu_errno = errno));
1470 uustring (S_WR_ERR_TEMP),
1471 strerror (uu_errno = errno));
1472 res = UURET_IOERR; 1484 res = UURET_IOERR;
1473 } 1485 }
1486 UUCLRBUF (uu_wbuf, dataout_buf);
1474 1487
1475 if (res != UURET_OK || (state != DONE && !uu_desperate)) { 1488 if (res != UURET_OK || (state != DONE && !uu_desperate)) {
1476 unlink (data->binfile); 1489 unlink (data->binfile);
1477 _FP_free (data->binfile); 1490 FP_free (data->binfile);
1478 data->binfile = NULL; 1491 data->binfile = NULL;
1479 data->state &= ~UUFILE_TMPFILE; 1492 data->state &= ~UUFILE_TMPFILE;
1480 data->state |= UUFILE_ERROR; 1493 data->state |= UUFILE_ERROR;
1481 1494
1482 if (res == UURET_OK && state != DONE) 1495 if (res == UURET_OK && state != DONE)
1494 /* 1507 /*
1495 * If this was a BinHex file, we must extract its data or resource fork 1508 * If this was a BinHex file, we must extract its data or resource fork
1496 */ 1509 */
1497 1510
1498 if (data->uudet == BH_ENCODED && data->binfile) { 1511 if (data->uudet == BH_ENCODED && data->binfile) {
1499 if ((ntmp = tempnam (NULL, "uu")) == NULL) { 1512#ifdef HAVE_MKSTEMP
1500 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1513 ntmp = malloc(strlen(tmpdir)+strlen(tmpprefix)+2);
1501 uustring (S_NO_TEMP_NAME)); 1514#else
1515 ntmp = tempnam (NULL);
1516#endif /* HAVE_MKSTEMP */
1517 if (ntmp == NULL) {
1518 UUMessage (UUMSG_ERROR, uustring (S_NO_TEMP_NAME));
1502 progress.action = 0; 1519 progress.action = 0;
1503 return UURET_NOMEM; 1520 return UURET_NOMEM;
1504 } 1521 }
1505 if ((datain = fopen (data->binfile, "rb")) == NULL) { 1522 if ((datain = fopen (data->binfile, "rb")) == NULL) {
1506 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1523 UUMessage (UUMSG_ERROR, uustring (S_NOT_OPEN_FILE),
1507 uustring (S_NOT_OPEN_FILE),
1508 data->binfile, strerror (uu_errno = errno)); 1524 data->binfile, strerror (uu_errno = errno));
1509 progress.action = 0; 1525 progress.action = 0;
1510 free (ntmp); 1526 free (ntmp);
1511 return UURET_IOERR; 1527 return UURET_IOERR;
1512 } 1528 }
1529 UUSETBUF (datain, datain_buf, uu_rbuf);
1530 FP_flockfile (datain);
1531
1532#ifdef HAVE_MKSTEMP
1533 strcpy(ntmp, tmpdir);
1534 strcat(ntmp, "/");
1535 strcat(ntmp, tmpprefix);
1536 if ((tmpfd = mkstemp(ntmp)) == -1 ||
1537 (dataout = fdopen(tmpfd, "wb")) == NULL) {
1538#else
1513 if ((dataout = fopen (ntmp, "wb")) == NULL) { 1539 if ((dataout = fopen (ntmp, "wb")) == NULL) {
1514 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1540#endif /* HAVE_MKSTEMP */
1541 UUMessage (UUMSG_ERROR,
1515 uustring (S_NOT_OPEN_TARGET), 1542 uustring (S_NOT_OPEN_TARGET),
1516 ntmp, strerror (uu_errno = errno)); 1543 ntmp, strerror (uu_errno = errno));
1517 progress.action = 0; 1544 progress.action = 0;
1518 fclose (datain); 1545 fclose (datain);
1546 UUCLRBUF (uu_rbuf, datain_buf);
1547#ifdef HAVE_MKSTEMP
1548 if (tmpfd != -1) {
1549 unlink(ntmp);
1550 close(tmpfd);
1551 }
1552#endif /* HAVE_MKSTEMP */
1519 free (ntmp); 1553 free (ntmp);
1520 return UURET_IOERR; 1554 return UURET_IOERR;
1521 } 1555 }
1556 UUSETBUF (dataout, dataout_buf, uu_wbuf);
1557 FP_flockfile (dataout);
1558
1522 /* 1559 /*
1523 * read fork lengths. remember they're in Motorola format 1560 * read fork lengths. remember they're in Motorola format
1524 */ 1561 */
1525 r[0] = fgetc (datain); 1562 r[0] = FP_getc (datain);
1526 hb = (int) r[0] + 22; 1563 hb = (int) r[0] + 22;
1527 fseek (datain, (int) r[0] + 12, SEEK_SET); 1564 fseek (datain, (int) r[0] + 12, SEEK_SET);
1528 fread (r, 1, 8, datain); 1565 fread (r, 1, 8, datain);
1529 1566
1530 dsize = (((long) 1 << 24) * (long) r[0]) + 1567 dsize = (((long) 1 << 24) * (long) r[0]) +
1534 rsize = (((long) 1 << 24) * (long) r[4]) + 1571 rsize = (((long) 1 << 24) * (long) r[4]) +
1535 (((long) 1 << 16) * (long) r[5]) + 1572 (((long) 1 << 16) * (long) r[5]) +
1536 (((long) 1 << 8) * (long) r[6]) + 1573 (((long) 1 << 8) * (long) r[6]) +
1537 ( (long) r[7]); 1574 ( (long) r[7]);
1538 1575
1539 UUMessage (uunconc_id, __LINE__, UUMSG_MESSAGE, 1576 UUMessage (UUMSG_MESSAGE, uustring (S_BINHEX_SIZES), dsize, rsize);
1540 uustring (S_BINHEX_SIZES),
1541 dsize, rsize);
1542 1577
1543 if (dsize == 0) { 1578 if (dsize == 0) {
1544 fseek (datain, dsize + hb + 2, SEEK_SET); 1579 fseek (datain, dsize + hb + 2, SEEK_SET);
1545 numbytes = rsize; 1580 numbytes = rsize;
1546 } 1581 }
1548 fseek (datain, hb, SEEK_SET); 1583 fseek (datain, hb, SEEK_SET);
1549 numbytes = dsize; 1584 numbytes = dsize;
1550 } 1585 }
1551 else { 1586 else {
1552 /* we should let the user have the choice here */ 1587 /* we should let the user have the choice here */
1553 UUMessage (uunconc_id, __LINE__, UUMSG_NOTE, 1588 UUMessage (UUMSG_NOTE, uustring (S_BINHEX_BOTH));
1554 uustring (S_BINHEX_BOTH));
1555 fseek (datain, hb, SEEK_SET); 1589 fseek (datain, hb, SEEK_SET);
1556 numbytes = dsize; 1590 numbytes = dsize;
1557 } 1591 }
1558 1592
1559 progress.action = 0; 1593 progress.action = 0;
1560 progress.partno = 0; 1594 progress.partno = 0;
1561 progress.numparts = 1; 1595 progress.numparts = 1;
1562 progress.fsize = (numbytes)?numbytes:-1; 1596 progress.fsize = numbytes ? numbytes : -1;
1563 progress.foffset = hb; 1597 progress.foffset = hb;
1564 progress.percent = 0; 1598 progress.percent = 0;
1565 progress.action = UUACT_COPYING; 1599 progress.action = UUACT_COPYING;
1566 1600
1567 /* 1601 /*
1568 * copy the chosen fork 1602 * copy the chosen fork
1569 */ 1603 */
1570 1604
1571 while (!feof (datain) && numbytes) { 1605 while (!FP_feof (datain) && numbytes) {
1572 if (UUBUSYPOLL(ftell(datain)-progress.foffset,progress.fsize)) { 1606 if (UUBUSYPOLL(ftell(datain)-progress.foffset,progress.fsize)) {
1573 UUMessage (uunconc_id, __LINE__, UUMSG_NOTE, 1607 UUMessage (UUMSG_NOTE, uustring (S_DECODE_CANCEL));
1574 uustring (S_DECODE_CANCEL));
1575 fclose (datain); 1608 fclose (datain);
1609 UUCLRBUF (uu_rbuf, datain_buf);
1576 fclose (dataout); 1610 fclose (dataout);
1611 UUCLRBUF (uu_wbuf, dataout_buf);
1577 unlink (ntmp); 1612 unlink (ntmp);
1578 free (ntmp); 1613 free (ntmp);
1579 return UURET_CANCEL; 1614 return UURET_CANCEL;
1580 } 1615 }
1581 1616
1582 bytes = fread (uugen_inbuffer, 1, 1617 bytes = fread (uugen_inbuffer, 1,
1583 (size_t) ((numbytes>1024)?1024:numbytes), datain); 1618 (size_t) ((numbytes>1024)?1024:numbytes), datain);
1584 1619
1585 if (ferror (datain) || (bytes == 0 && !feof (datain))) { 1620 if (ferror (datain) || (bytes == 0 && !FP_feof (datain))) {
1586 progress.action = 0; 1621 progress.action = 0;
1587 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1622 UUMessage (UUMSG_ERROR,
1588 uustring (S_SOURCE_READ_ERR), 1623 uustring (S_SOURCE_READ_ERR),
1589 data->binfile, strerror (uu_errno = errno)); 1624 data->binfile, strerror (uu_errno = errno));
1590 fclose (datain); 1625 fclose (datain);
1626 UUCLRBUF (uu_rbuf, datain_buf);
1591 fclose (dataout); 1627 fclose (dataout);
1628 UUCLRBUF (uu_wbuf, dataout_buf);
1592 unlink (ntmp); 1629 unlink (ntmp);
1593 free (ntmp); 1630 free (ntmp);
1594 return UURET_IOERR; 1631 return UURET_IOERR;
1595 } 1632 }
1596 if (fwrite (uugen_inbuffer, 1, bytes, dataout) != bytes) { 1633 if (fwrite (uugen_inbuffer, 1, bytes, dataout) != bytes) {
1597 progress.action = 0; 1634 progress.action = 0;
1598 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1635 UUMessage (UUMSG_ERROR,
1599 uustring (S_WR_ERR_TARGET), 1636 uustring (S_WR_ERR_TARGET),
1600 ntmp, strerror (uu_errno = errno)); 1637 ntmp, strerror (uu_errno = errno));
1601 fclose (datain); 1638 fclose (datain);
1639 UUCLRBUF (uu_rbuf, datain_buf);
1602 fclose (dataout); 1640 fclose (dataout);
1641 UUCLRBUF (uu_wbuf, dataout_buf);
1603 unlink (ntmp); 1642 unlink (ntmp);
1604 free (ntmp); 1643 free (ntmp);
1605 return UURET_IOERR; 1644 return UURET_IOERR;
1606 } 1645 }
1607 numbytes -= bytes; 1646 numbytes -= bytes;
1608 } 1647 }
1609 1648
1610 if (numbytes) { 1649 if (numbytes) {
1611 UUMessage (uunconc_id, __LINE__, UUMSG_WARNING, 1650 UUMessage (UUMSG_WARNING,
1612 uustring (S_SHORT_BINHEX), 1651 uustring (S_SHORT_BINHEX),
1613 (data->filename)?data->filename: 1652 (data->filename)?data->filename:
1614 (data->subfname)?data->subfname:"???", 1653 (data->subfname)?data->subfname:"???",
1615 numbytes); 1654 numbytes);
1616 } 1655 }
1618 /* 1657 /*
1619 * replace temp file 1658 * replace temp file
1620 */ 1659 */
1621 1660
1622 fclose (datain); 1661 fclose (datain);
1662 UUCLRBUF (uu_rbuf, datain_buf);
1623 if (fclose (dataout)) { 1663 if (fclose (dataout)) {
1624 UUMessage (uunconc_id, __LINE__, UUMSG_ERROR, 1664 UUCLRBUF (uu_wbuf, dataout_buf);
1665 UUMessage (UUMSG_ERROR,
1625 uustring (S_WR_ERR_TARGET), 1666 uustring (S_WR_ERR_TARGET),
1626 ntmp, strerror (uu_errno = errno)); 1667 ntmp, strerror (uu_errno = errno));
1627 unlink (ntmp); 1668 unlink (ntmp);
1628 free (ntmp); 1669 free (ntmp);
1629 return UURET_IOERR; 1670 return UURET_IOERR;
1630 } 1671 }
1672 UUCLRBUF (uu_wbuf, dataout_buf);
1631 1673
1632 if (unlink (data->binfile)) { 1674 if (unlink (data->binfile)) {
1633 UUMessage (uunconc_id, __LINE__, UUMSG_WARNING, 1675 UUMessage (UUMSG_WARNING,
1634 uustring (S_TMP_NOT_REMOVED), 1676 uustring (S_TMP_NOT_REMOVED),
1635 data->binfile, strerror (uu_errno = errno)); 1677 data->binfile, strerror (uu_errno = errno));
1636 } 1678 }
1637 1679
1638 free (data->binfile); 1680 free (data->binfile);
1659 */ 1701 */
1660 1702
1661 memset (&myenv, 0, sizeof (headers)); 1703 memset (&myenv, 0, sizeof (headers));
1662 UUScanHeader (datain, &myenv); 1704 UUScanHeader (datain, &myenv);
1663 1705
1664 if (_FP_stristr (myenv.ctenc, "uu") != NULL) 1706 if (FP_stristr (myenv.ctenc, "uu") != NULL)
1665 encoding = UU_ENCODED; 1707 encoding = UU_ENCODED;
1666 else if (_FP_stristr (myenv.ctenc, "xx") != NULL) 1708 else if (FP_stristr (myenv.ctenc, "xx") != NULL)
1667 encoding = XX_ENCODED; 1709 encoding = XX_ENCODED;
1668 else if (_FP_stricmp (myenv.ctenc, "base64") == 0) 1710 else if (FP_stricmp (myenv.ctenc, "base64") == 0)
1669 encoding = B64ENCODED; 1711 encoding = B64ENCODED;
1670 else if (_FP_stricmp (myenv.ctenc, "quoted-printable") == 0) 1712 else if (FP_stricmp (myenv.ctenc, "quoted-printable") == 0)
1671 encoding = QP_ENCODED; 1713 encoding = QP_ENCODED;
1672 else 1714 else
1673 encoding = PT_ENCODED; 1715 encoding = PT_ENCODED;
1674 1716
1675 UUkillheaders (&myenv); 1717 UUkillheaders (&myenv);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines