… | |
… | |
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 | |
|
|
58 | char * 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 | |
190 | int |
184 | static int |
191 | UUBrokenByNetscape (char *string) |
185 | UUBrokenByNetscape (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 & + co, |
220 | * in href strings, I'm now using two passes, the first one for & + co, |
230 | * the second one for hrefs. |
221 | * the second one for hrefs. |
231 | */ |
222 | */ |
232 | |
223 | |
233 | int |
224 | static int |
234 | UUNetscapeCollapse (char *string) |
225 | UUNetscapeCollapse (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, "&", 5) == 0) { p1+=5; *p2++='&'; res=1; } |
238 | if (FP_strnicmp (p1, "&", 5) == 0) { p1+=5; *p2++='&'; res=1; } |
248 | else if (_FP_strnicmp (p1, "<", 4) == 0) { p1+=4; *p2++='<'; res=1; } |
239 | else if (FP_strnicmp (p1, "<", 4) == 0) { p1+=4; *p2++='<'; res=1; } |
249 | else if (_FP_strnicmp (p1, ">", 4) == 0) { p1+=4; *p2++='>'; res=1; } |
240 | else if (FP_strnicmp (p1, ">", 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 | |
295 | int |
287 | int |
296 | UUValidData (char *ptr, int encoding, int *bhflag) |
288 | UUValidData (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 | |
738 | int |
723 | static int |
739 | UUDecodeQP (FILE *datain, FILE *dataout, int *state, |
724 | UUDecodeQP (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 | |
836 | int |
821 | static int |
837 | UUDecodePT (FILE *datain, FILE *dataout, int *state, |
822 | UUDecodePT (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 | } |
… | |
… | |
962 | int |
939 | int |
963 | UUDecodePart (FILE *datain, FILE *dataout, int *state, |
940 | UUDecodePart (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 | |
1304 | int |
1281 | int |
1305 | UUDecode (uulist *data) |
1282 | UUDecode (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); |