File indexing completed on 2018-03-02 18:45:01 UTC
view on githubraw file Latest commit e768bd12 on 2008-02-26 17:05:00 UTC
ec6cf3b09d Ed H*0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <stdio.h>
e768bd1221 Jean*0026 #include <stdlib.h>
ec6cf3b09d Ed H*0027 #include <ctype.h>
0028 #include <string.h>
e768bd1221 Jean*0029 #include <unistd.h>
ec6cf3b09d Ed H*0030 #include "xmalloc.h"
0031 #include "common.h"
0032 #include "part.h"
0033
0034 extern char *os_idtodir(char *id);
0035 extern FILE *os_newtypedfile(char *fname, char *contentType, int flags, params contentParams);
0036 extern FILE *os_createnewfile(char *fname);
e768bd1221 Jean*0037 extern int os_binhex(struct part *inpart, int part, int nparts);
0038 extern void os_closetypedfile(FILE *outfile);
0039 extern void os_donewithdir(char *dir);
0040 extern void os_perror(char *str);
0041 extern void chat(char *s);
0042
0043 extern void part_ungets(char *s, struct part *part);
0044 extern void part_close(struct part *part);
0045 extern int handleMessage(struct part *inpart, char *defaultContentType,
0046 int inAppleDouble, int extractText);
ec6cf3b09d Ed H*0047
0048 static FILE *startDescFile(char *fname);
e768bd1221 Jean*0049 static void uudecodeline(char *line, FILE *outfile);
ec6cf3b09d Ed H*0050
e768bd1221 Jean*0051 int parseSubject(char *subject, char **fnamep, int *partp, int *npartsp);
0052 int saveUuFile(struct part *inpart, char *fname, int part, int nparts,
0053 char *firstline);
0054 int descEnd(char *line);
0055 int uudecodefiles(char *dir, int nparts);
ec6cf3b09d Ed H*0056
0057
0058 #define UULENGTH 62
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 static char bchar[256] = {
0071 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0072 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0073 1, 0, 0, 2, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1,
0074 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1,
0075 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0076 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
0077 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0078 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0079 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0080 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0081 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0082 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0083 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0084 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0085 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0086 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0087 };
0088
0089
0090
0091
0092 int handleUuencode(struct part *inpart, char *subject, int extractText)
0093 {
0094 char *fname = 0, *tmpfname;
0095 int part, nparts;
0096 int tmppart, tmpnparts;
0097 char buf[1024], buf2[1024];
0098 char fnamebuf[80];
0099 char *boundary_end, *p;
0100 int wantdescfile = 0;
0101 FILE *descfile = 0;
0102
0103
0104 if (parseSubject(subject, &fname, &part, &nparts) != 0) {
0105 part = -1;
0106 }
0107 if (part == 0) {
0108 return saveUuFile(inpart, fname, part, nparts, (char *)0);
0109 }
0110 if (part == 1) {
0111 wantdescfile = 1;
0112 }
0113
0114
0115 while (part_gets(buf, sizeof(buf), inpart)) {
0116
0117 if (!strncmp(buf, "begin ", 6) &&
0118 isdigit(buf[6]) && isdigit(buf[7]) && isdigit(buf[8]) &&
0119 buf[9] == ' ') {
0120 if (part == -1) {
0121
0122
0123
0124
0125 return saveUuFile(inpart, (char *)0, 1, 0, buf);
0126 }
0127 else {
0128 if (descfile) fclose(descfile);
0129 return saveUuFile(inpart, fname, part, nparts, buf);
0130 }
0131 }
0132 else if (!strncmp(buf, "section ", 8) && isdigit(buf[8])) {
0133 tmppart = 0;
0134 for (p = buf+8; isdigit(*p); p++) tmppart = tmppart*10 + *p - '0';
0135 if (tmppart == 0) continue;
0136 if (strncmp(p, " of ", 4) == 0) {
0137
0138
0139
0140 for (p += 4; *p && strncmp(p, " of file ", 9) != 0; p++);
0141 if (!*p) continue;
0142 p += 9;
0143 tmpfname = p;
0144 p = strchr(p, ' ');
0145 if (!p) continue;
0146 *p = '\0';
0147 if (descfile) fclose(descfile);
0148 return saveUuFile(inpart, tmpfname, tmppart, 0, (char *)0);
0149 }
0150 else if (*p == '/' && isdigit(p[1])) {
0151
0152
0153
0154 tmpnparts = 0;
0155 for (p++; isdigit(*p); p++) {
0156 tmpnparts = tmpnparts*10 + *p - '0';
0157 }
0158 while (*p && isspace(*p)) p++;
0159 if (tmppart > tmpnparts || strncmp(p, "file ", 5) != 0) {
0160 continue;
0161 }
0162 tmpfname = p+5;
0163 p = strchr(tmpfname, ' ');
0164 if (!p) continue;
0165 *p = '\0';
0166 if (descfile) fclose(descfile);
0167 return saveUuFile(inpart, tmpfname, tmppart, tmpnparts,
0168 (char *)0);
0169 }
0170 }
0171 else if (!strncmp(buf, "POST V", 6)) {
0172
0173
0174
0175 p = strchr(buf+6, ' ');
0176 if (!p) continue;
0177 tmpfname = p+1;
0178 p = strchr(tmpfname, ' ');
0179 if (!p || strncmp(p, " (Part ", 7) != 0) continue;
0180 *p = '\0';
0181 p += 7;
0182 tmppart = 0;
0183 while (isdigit(*p)) tmppart = tmppart*10 + *p++ - '0';
0184 if (tmppart == 0 || *p++ != '/') continue;
0185 tmpnparts = 0;
0186 while (isdigit(*p)) tmpnparts = tmpnparts*10 + *p++ - '0';
0187 if (tmppart > tmpnparts || *p != ')') continue;
0188 if (descfile) fclose(descfile);
0189 return saveUuFile(inpart, tmpfname, tmppart, tmpnparts, (char *)0);
0190 }
0191 else if (!strncmp(buf, "File: ", 6)) {
0192
0193
0194
0195 tmpfname = buf+6;
0196 p = strchr(tmpfname, ' ');
0197 if (!p || strncmp(p, " -- part ", 9) != 0) continue;
0198 *p = '\0';
0199 p += 9;
0200 tmppart = 0;
0201 while (isdigit(*p)) tmppart = tmppart*10 + *p++ - '0';
0202 if (tmppart == 0 || strncmp(p, " of ", 4) != 0) continue;
0203 p += 4;
0204 tmpnparts = 0;
0205 while (isdigit(*p)) tmpnparts = tmpnparts*10 + *p++ - '0';
0206 if (tmppart > tmpnparts || strncmp(p, " -- ", 4) != 0) continue;
0207 if (descfile) fclose(descfile);
0208 return saveUuFile(inpart, tmpfname, tmppart, tmpnparts, (char *)0);
0209 }
0210 else if (!strncmp(buf, "[Section: ", 10)) {
0211
0212
0213
0214 tmppart = 0;
0215 for (p = buf+10; isdigit(*p); p++) tmppart = tmppart*10 + *p - '0';
0216 if (tmppart == 0) continue;
0217 tmpnparts = 0;
0218 for (p++; isdigit(*p); p++) {
0219 tmpnparts = tmpnparts*10 + *p - '0';
0220 }
0221 while (*p && isspace(*p)) p++;
0222 if (tmppart > tmpnparts || strncmp(p, "File: ", 6) != 0) {
0223 continue;
0224 }
0225 tmpfname = p+6;
0226 p = strchr(tmpfname, ' ');
0227 if (!p) continue;
0228 *p = '\0';
0229 if (descfile) fclose(descfile);
0230 return saveUuFile(inpart, tmpfname, tmppart, tmpnparts, (char *)0);
0231 }
0232 else if (*buf == '[') {
0233
0234
0235
0236
0237 tmpfname = buf+1;
0238 p = strchr(tmpfname, ' ');
0239 if (!p) continue;
0240 *p++ = '\0';
0241 while (p && strncmp(p, "- part ", 7) != 0) {
0242 p = strchr(p+1, '-');
0243 }
0244 if (!p) continue;
0245 p += 7;
0246 tmppart = 0;
0247 while (isdigit(*p)) tmppart = tmppart*10 + *p++ - '0';
0248 if (tmppart == 0 || strncmp(p, " of ", 4) != 0) continue;
0249 p += 4;
0250 tmpnparts = 0;
0251 while (isdigit(*p)) tmpnparts = tmpnparts*10 + *p++ - '0';
0252 if (tmppart > tmpnparts || *p != ']') continue;
0253 if (descfile) fclose(descfile);
0254 return saveUuFile(inpart, tmpfname, tmppart, tmpnparts, (char *)0);
0255 }
0256 else if (fname && part > 0 && nparts > 0 && part <= nparts &&
0257 (!strncmp(buf, "BEGIN", 5) ||
0258 !strncmp(buf, "--- BEGIN ---", 12) ||
0259 (buf[0] == 'M' && strlen(buf) == UULENGTH))) {
0260
0261
0262
0263
0264 if (descfile) fclose(descfile);
0265 return saveUuFile(inpart, fname, part, nparts, buf);
0266 }
0267 else if (!strncasecmp(buf, "x-file-name: ", 13)) {
0268 for (p = buf + 13; *p && !isspace(*p); p++);
0269 *p = '\0';
0270 strncpy(fnamebuf, buf+13, sizeof(fnamebuf)-1);
0271 fnamebuf[sizeof(fnamebuf)-1] = '\0';
0272 fname = fnamebuf;
0273 continue;
0274 }
0275 else if (!strncasecmp(buf, "x-part: ", 8)) {
0276 tmppart = atoi(buf+8);
0277 if (tmppart > 0) part = tmppart;
0278 continue;
0279 }
0280 else if (!strncasecmp(buf, "x-part-total: ", 14)) {
0281 tmpnparts = atoi(buf+14);
0282 if (tmpnparts > 0) nparts = tmpnparts;
0283 continue;
0284 }
0285 else if (part == 1 && fname && !descfile &&
0286 !strncasecmp(buf, "x-file-desc: ", 13)) {
e768bd1221 Jean*0287 if ((descfile = startDescFile(fname))) {
ec6cf3b09d Ed H*0288 fputs(buf+13, descfile);
0289 fclose(descfile);
0290 descfile = 0;
0291 }
0292 continue;
0293 }
0294 else if (!strcmp(buf,
0295 "(This file must be converted with BinHex 4.0)\n")) {
0296 if (descfile) fclose(descfile);
0297 return os_binhex(inpart, 1, 1);
0298 }
0299 else if (!strncasecmp(buf, "content-", 8)) {
0300
0301
0302
0303
0304 p = buf+8;
0305
0306 while (*p) {
0307 if (*p == ':' || *p <= ' ' || *p >= '\177') break;
0308 p++;
0309 }
0310 if (*p == ':') {
0311 part_ungets(buf, inpart);
0312 if (descfile) fclose(descfile);
0313 return handleMessage(inpart, "text/plain", 0, extractText);
0314 }
0315 }
0316 if (buf[0] == '-' && buf[1] == '-') {
0317
0318
0319
0320
0321
0322 p = buf+2;
0323 while (*p) {
0324 if (!bchar[(unsigned char)*p]) break;
0325 p++;
0326 }
0327 if (*p != '\n') {
0328
0329
0330
0331
0332 p = buf + 2;
0333 }
0334
0335 while (p > buf+2 && p[-1] == ' ') p--;
0336
0337
0338
0339
0340
0341 if (p - buf > 2 && p - buf <= 72 &&
0342 part_gets(buf2, sizeof(buf2), inpart)) {
0343 boundary_end = p;
0344 p = buf2;
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357 while (*p) {
0358 if (*p == ':' || *p <= ' ' || *p >= '\177') break;
0359 p++;
0360 }
0361
0362
0363 part_ungets(buf2, inpart);
0364
0365 if (p > buf2 && *p == ':') {
0366
0367 part_ungets(buf, inpart);
0368
0369
0370
0371
0372
0373 *boundary_end = '\0';
0374 sprintf(buf2,
0375 "Content-type: multipart/mixed; boundary=\"%s\"\n\n",
0376 buf+2);
0377 part_ungets(buf2, inpart);
0378
0379 if (descfile) fclose(descfile);
0380 return handleMessage(inpart, "text/plain", 0, extractText);
0381 }
0382 }
0383 }
0384
0385
0386
0387
0388
0389 if (wantdescfile && !descfile) {
0390 for (p = buf; *p && isspace(*p); p++);
0391 if (*p) {
0392 if (!strncasecmp(p, "x-", 2)) {
0393
0394
0395
0396
0397
0398 while (*p != ':' && *p > ' ' && *p < '\177') p++;
0399 if (*p == ':') continue;
0400 }
0401 if (!descEnd(buf) && (descfile = startDescFile(fname))) {
0402 fputs(buf, descfile);
0403 }
0404 wantdescfile = 0;
0405 }
0406 }
0407 else if (descfile) {
0408 if (descEnd(buf)) {
0409 fclose(descfile);
0410 descfile = 0;
0411 }
0412 else {
0413 fputs(buf, descfile);
0414 }
0415 }
0416 }
0417
0418 if (descfile) fclose(descfile);
0419 return 0;
0420 }
0421
0422
0423
0424
0425
0426
0427
0428 int
0429 saveUuFile(struct part *inpart, char *fname, int part, int nparts, char *firstline)
0430 {
0431 char buf[1024];
0432 char *dir;
0433 FILE *partfile;
0434
0435 if (fname) {
0436 sprintf(buf, "Saving part %d ", part);
0437 if (nparts) sprintf(buf+strlen(buf), "of %d ", nparts);
0438 strcat(buf, fname);
0439 chat(buf);
0440 }
0441 else fname = "unknown";
0442
0443
0444 dir = os_idtodir(fname);
0445 if (!dir) return 1;
0446 sprintf(buf, "%s%d", dir, part);
0447 partfile = os_createnewfile(buf);
0448 if (!partfile) {
0449 os_perror(buf);
0450 return 1;
0451 }
0452 if (firstline) fputs(firstline, partfile);
0453 while (part_gets(buf, sizeof(buf), inpart)) {
0454 fputs(buf, partfile);
0455 if (nparts == 0 && strcmp(buf, "end\n") == 0) {
0456
0457 nparts = part;
0458 fclose(partfile);
0459 sprintf(buf, "%sCT", dir);
0460 partfile = os_createnewfile(buf);
0461 if (!partfile) {
0462 os_perror(buf);
0463 }
0464 else {
0465 fprintf(partfile, "%d\n", nparts);
0466 }
0467 break;
0468 }
0469 }
0470 fclose(partfile);
0471
0472
0473 if (nparts == 0) {
0474 sprintf(buf, "%sCT", dir);
e768bd1221 Jean*0475 if ((partfile = fopen(buf, "r"))) {
ec6cf3b09d Ed H*0476 if (fgets(buf, sizeof(buf), partfile)) {
0477 nparts = atoi(buf);
0478 if (nparts < 0) nparts = 0;
0479 }
0480 fclose(partfile);
0481 }
0482 }
0483
0484 if (nparts == 0) return 0;
0485
0486
0487
0488
0489 for (part = nparts; part; part--) {
0490 sprintf(buf, "%s%d", dir, part);
0491 partfile = fopen(buf, "r");
0492 if (partfile) {
0493 fclose(partfile);
0494 }
0495 else {
0496 return 0;
0497 }
0498 }
0499
0500 return uudecodefiles(dir, nparts);
0501 }
0502
0503
0504
0505
0506
0507 int
0508 parseSubject(char *subject, char **fnamep, int *partp, int *npartsp)
0509 {
0510 char *scan, *bak, *start;
0511 int part = -1, nparts = 0, hasdot = 0;
0512
0513
0514 if (!subject) return 1;
0515
0516
0517 scan = subject;
0518 while (*scan == ' ' || *scan == '\t' || *scan == '-') scan++;
0519 if (!strncasecmp(scan, "repost", 6)) {
0520 for (scan += 6; *scan == ' ' || *scan == '\t'
0521 || *scan == ':' || *scan == '-'; scan++);
0522 }
0523
0524
0525 if (!strncasecmp(scan, "re:", 3)) return 1;
0526
0527
0528
0529
0530
0531
0532
0533 do {
0534 while (*scan != '\n' && !isalnum(*scan) && *scan != '_') ++scan;
0535 *fnamep = start = scan;
0536 while (isalnum(*scan) || *scan == '-' || *scan == '+' || *scan == '&'
0537 || *scan == '_' || *scan == '.') {
0538 if (*scan++ == '.') hasdot = 1;
0539 }
0540 if (!*scan || *scan == '\n') return 1;
0541 } while (start == scan
0542 || (start[0] == 'v' && isdigit(start[1]) && *scan == ':'));
0543 *scan++ = '\0';
0544
0545
0546
0547
0548 if (!hasdot) {
0549 while (*(start = scan) != '\0' && *scan != '\n') {
0550 while (isspace(*start)) ++start;
0551 for (scan = start; isalnum(*scan) || *scan == '-' || *scan == '+'
0552 || *scan == '&' || *scan == '_' || *scan == '.'; ++scan) {
0553 if (*scan == '.' &&
0554 (!isdigit(scan[-1]) || !isdigit(scan[1]))) {
0555 hasdot = 1;
0556 }
0557 }
0558 if (hasdot && scan > start) {
0559 *fnamep = start;
0560 *scan++ = '\0';
0561 break;
0562 }
0563 while (*scan && *scan != '\n' && !isalnum(*scan)) ++scan;
0564 }
0565 scan = *fnamep + strlen(*fnamep) + 1;
0566 }
0567
0568
0569 while (*scan && *scan != '\n') {
0570
0571 if (*scan == 'v' && isdigit(scan[1])) {
0572 ++scan;
0573 while (isdigit(*scan)) ++scan;
0574 }
0575
0576 if (isdigit(*scan) &&
0577 (scan[1] == '/'
0578 || (scan[1] == ' ' && scan[2] == '/')
0579 || (scan[1] == ' ' && scan[2] == 'o' && scan[3] == 'f')
0580 || (scan[1] == '-' && scan[2] == 'o' && scan[3] == 'f')
0581 || (scan[1] == 'o' && isdigit(scan[2])))) {
0582 while (isdigit(scan[-1])) scan--;
0583 part = 0;
0584 while (isdigit(*scan)) {
0585 part = part * 10 + *scan++ - '0';
0586 }
0587 while (*scan != '\0' && *scan != '\n' && !isdigit(*scan)) scan++;
0588 if (isdigit(*scan)) {
0589 nparts = 0;
0590 while (isdigit(*scan)) {
0591 nparts = nparts * 10 + *scan++ - '0';
0592 }
0593 }
0594 break;
0595 }
0596
0597
0598 if (!strncasecmp("part", scan, 4)) {
0599 if (scan[4] == 's') {
0600 for (bak = scan; bak >= subject && !isdigit(*bak); bak--);
0601 if (bak > subject) {
0602 while (bak > subject && isdigit(bak[-1])) bak--;
0603 nparts = 0;
0604 while (isdigit(*bak)) {
0605 nparts = nparts * 10 + *bak++ - '0';
0606 }
0607 }
0608 } else {
0609 while (*scan && *scan != '\n' && !isdigit(*scan)) scan++;
0610 bak = scan - 1;
0611 if (isdigit(*scan)) {
0612 part = 0;
0613 do {
0614 part = part * 10 + *scan++ - '0';
0615 } while (isdigit(*scan));
0616 }
0617 scan = bak;
0618 }
0619 }
0620 scan++;
0621 }
0622
0623 if (nparts == 0 || part == -1 || part > nparts) return 1;
0624 *partp = part;
0625 *npartsp = nparts;
0626 return 0;
0627 }
0628
0629
0630
0631
0632 int
0633 descEnd(char *line)
0634 {
0635 return !strncmp(line, "---", 3) ||
0636 !strncmp(line, "#!", 2) ||
0637 !strncasecmp(line, "part=", 5) ||
0638 !strncasecmp(line, "begin", 5);
0639 }
0640
0641
0642
0643
0644
0645
0646 static FILE *startDescFile(char *fname)
0647 {
0648 char buf[1024];
0649 char *dir;
0650 FILE *descfile;
0651
0652
0653 dir = os_idtodir(fname);
0654 if (!dir) return 0;
0655 sprintf(buf, "%s0", dir);
0656
0657
0658 descfile = fopen(buf, "r");
0659 if (descfile) {
0660 fclose(descfile);
0661 return 0;
0662 }
0663
0664 descfile = os_createnewfile(buf);
0665 if (!descfile) {
0666 os_perror(buf);
0667 return 0;
0668 }
0669 return descfile;
0670 }
0671
0672
0673
0674
0675 int
0676 uudecodefiles(char *dir, int nparts)
0677 {
0678 int part;
0679 enum {st_start, st_inactive, st_decode, st_nextlast, st_last,
0680 st_binhex} state;
0681 FILE *infile;
0682 FILE *outfile = NULL;
0683 struct part *inpart;
0684 char buf[1024];
0685 char lastline[UULENGTH+1];
0686 char *fname, *p;
0687 char *contentType = "application/octet-stream";
0688 int line_length = 0;
0689
0690
0691 sprintf(buf, "%s0", dir);
0692 infile = fopen(buf, "r");
0693 if (infile) {
0694 outfile = os_createnewfile(TEMPFILENAME);
0695 if (outfile) {
0696 while (fgets(buf, sizeof(buf), infile)) {
0697 fputs(buf, outfile);
0698 }
0699 fclose(outfile);
0700 outfile = NULL;
0701 }
0702 fclose(infile);
0703 sprintf(buf, "%s0", dir);
0704 remove(buf);
0705 }
0706
0707 state = st_start;
0708
0709
0710 for (part = 1; part <= nparts; part++) {
0711 sprintf(buf, "%s%d", dir, part);
0712 infile = fopen(buf, "r");
0713 if (!infile) {
0714 os_perror(buf);
0715 if (outfile) fclose(outfile);
0716 remove(TEMPFILENAME);
0717 return 1;
0718 }
0719
0720 while (fgets(buf, sizeof(buf), infile)) {
0721 switch (state) {
0722 case st_start:
0723
0724 if (!strcmp(buf,
0725 "(This file must be converted with BinHex 4.0)\n")) {
0726 state = st_binhex;
0727 inpart = part_init(infile);
0728 os_binhex(inpart, part, nparts);
0729 part_close(inpart);
0730 goto endbinhex;
0731 }
0732 if (strncmp(buf, "begin ", 6)) break;
0733
0734 p = buf + 6;
0735 while (*p && !isspace(*p)) p++;
0736 while (*p && isspace(*p)) p++;
0737 fname = p;
0738 while (*p && !isspace(*p)) p++;
0739 *p = '\0';
0740 if (!*fname) return 1;
0741
0742
e768bd1221 Jean*0743 if ((p = strrchr(fname, '.'))) {
ec6cf3b09d Ed H*0744 if (!strcasecmp(p, ".gif")) contentType = "image/gif";
0745 if (!strcasecmp(p, ".jpg")) contentType = "image/jpeg";
0746 if (!strcasecmp(p, ".jpeg")) contentType = "image/jpeg";
0747 if (!strcasecmp(p, ".mpg")) contentType = "video/mpeg";
0748 if (!strcasecmp(p, ".mpeg")) contentType = "video/mpeg";
0749 }
0750
0751
0752 outfile = os_newtypedfile(fname, contentType, FILE_BINARY,
0753 (params) 0);
0754 if (!outfile) {
0755 fclose(infile);
0756 return 1;
0757 }
0758 state = st_decode;
0759 break;
0760
0761 case st_inactive:
0762 if (*buf != 'M' || strlen(buf) != line_length) {
0763 if (*buf == 'B' && !strncmp(buf, "BEGIN", 5)) {
0764 state = st_decode;
0765 }
0766 break;
0767 }
0768 state = st_decode;
0769
0770 case st_decode:
0771 if (line_length == 0) line_length = strlen(buf);
0772 if (*buf == 'M' && strlen(buf) == line_length) {
0773 uudecodeline(buf, outfile);
0774 break;
0775 }
0776 if (strlen(buf) > line_length) {
0777 state = st_inactive;
0778 break;
0779 }
0780
0781
0782
0783
0784 strcpy(lastline, buf);
0785 if (*buf == ' ' || *buf == '`') {
0786 state = st_last;
0787 }
0788 else {
0789 state = st_nextlast;
0790 }
0791 break;
0792
0793 case st_nextlast:
0794 if (*buf == ' ' || *buf == '`') {
0795 state = st_last;
0796 }
0797 else {
0798 state = st_inactive;
0799 }
0800 break;
0801
0802 case st_last:
0803 if (!strncmp(buf, "end", 3) && isspace(buf[3])) {
0804
0805 uudecodeline(lastline, outfile);
0806 fclose(infile);
0807 os_closetypedfile(outfile);
0808 for (;part <= nparts; part++) {
0809 sprintf(buf, "%s%d", dir, part);
0810 remove(buf);
0811 }
0812 sprintf(buf, "%sCT", dir);
0813 remove(buf);
0814 os_donewithdir(dir);
0815 return 0;
0816 }
0817 state = st_inactive;
0818 break;
0819
0820 case st_binhex:
0821 if (strncmp(buf, "---", 3)) break;
0822 inpart = part_init(infile);
0823 os_binhex(inpart, part, nparts);
0824 part_close(inpart);
0825 goto endbinhex;
0826 }
0827 }
0828 if (state != st_binhex) state = st_inactive;
0829 fclose(infile);
0830 endbinhex:
0831 sprintf(buf, "%s%d", dir, part);
0832 remove(buf);
0833 }
0834 if (outfile) os_closetypedfile(outfile);
0835 if (state == st_binhex) os_binhex(0, 0, 0);
0836 sprintf(buf, "%sCT", dir);
0837 remove(buf);
0838 os_donewithdir(dir);
0839 return 0;
0840 }
0841
0842 #define DEC(c) (((c) - ' ') & 077)
0843
0844
0845
0846
e768bd1221 Jean*0847 static void uudecodeline(char *line, FILE *outfile)
ec6cf3b09d Ed H*0848 {
0849 int c, len;
0850
0851 len = DEC(*line++);
0852 while (len) {
0853 c = DEC(*line) << 2 | DEC(line[1]) >> 4;
0854 putc(c, outfile);
0855 if (--len) {
0856 c = DEC(line[1]) << 4 | DEC(line[2]) >> 2;
0857 putc(c, outfile);
0858 if (--len) {
0859 c = DEC(line[2]) << 6 | DEC(line[3]);
0860 putc(c, outfile);
0861 len--;
0862 }
0863 }
0864 line += 4;
0865 }
0866 }
0867
0868