/* ** ** Copyright (C) 1993 Swedish University Network (SUNET) ** ** ** This program is developed by UDAC, Uppsala University by commission ** of the Swedish University Network (SUNET). ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITTNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ** ** ** Martin.Wendel@its.uu.se ** Torbjorn.Wictorin@its.uu.se ** ** ITS ** P.O. Box 887 ** S-751 08 Uppsala ** Sweden ** */ #include "emil.h" #include int get_applesingle_binary(struct message *m) { struct data *d; struct data *r = NULL; unsigned long magic; unsigned long version; unsigned long filler; unsigned short entries; unsigned long doffset; unsigned long dlength; int i; doffset = dlength = 0; #ifdef DEBUG if (edebug) fprintf(stderr, "get_applesingle_binary().\n"); #endif if ((d = m->td) != NULL) d->offset = d->bodystart; else { #ifdef DEBUG if (edebug) fprintf(stderr, "get_applesingle_binary: empty input.\n"); #endif return(NOK); } /* Check magic number */ if (getlong(&magic, d) != OK) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: magic number: short file.\n"); #endif return(NOK); } if (magic != 0x00051600) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: Wrong magic number %lX.\n", magic); #endif return(NOK); } #ifdef DEBUG if (edebug) fprintf(stderr, "- get_applesingle_binary: got magic number\n"); #endif /* Check version number */ if (getlong(&version, d) != OK) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: version number: short file.\n"); #endif return(NOK); } if (version != 0x00020000) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: Wrong magic number.\n"); #endif return(NOK); } #ifdef DEBUG if (edebug) fprintf(stderr, "- get_applesingle_binary: got version number\n"); #endif /* Check filler */ for (i = 0; i < 4; i++) { if (getlong(&filler, d) != OK) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: filler: short file.\n"); #endif return(NOK); } if (filler != 0x00000000) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: Wrong filler.\n"); #endif return(NOK); } } #ifdef DEBUG if (edebug) fprintf(stderr, "- get_applesingle_binary: got filler\n"); #endif /* Get entries */ if (getshort(&entries, d) != OK) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: entries: short file.\n"); #endif return(NOK); } if (entries < 1) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: emtpy entries, (failed)\n"); #endif return(NOK); } #ifdef DEBUG if (edebug) fprintf(stderr, "- get_applesingle_binary: got %u entries\n", entries); #endif /* Get entries */ for (i = 0; i < entries; i++) { unsigned long entry_id; unsigned long offset; unsigned long length; /* Get entry ID */ if (getlong(&entry_id, d) != OK) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: entry ID: short file %lu.\n", d->offset); #endif return(NOK); } /* Get offset */ if (getlong(&offset, d) != OK) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: offset: short file %lu.\n", d->offset); #endif return(NOK); } /* Get length */ if (getlong(&length, d) != OK) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: length: short file %lu.\n", d->offset); #endif return(NOK); } #ifdef DEBUG if (edebug) fprintf(stderr, "- get_applesingle_binary: got entry: id=%lu, offset=%lu, length=%lu\n", entry_id, offset, length); #endif switch(entry_id) { case 1: /* Data fork */ doffset = d->bodystart + offset; dlength = length; if (check_length(d, doffset + dlength) != OK) { #ifdef DEBUG if (edebug) { fprintf(stderr, "* get_applesingle_binary: data fork: short file %lu.\n", d->offset); fprintf(stderr, "* get_applesingle_binary: suggested offset: %lu suggested length: %lu\n", offset, length); fprintf(stderr, "* get_applesingle_binary: bodystart %lu end %lu\n", d->bodystart, d->bodyend); } #endif return(NOK); } #ifdef DEBUG if (edebug) fprintf(stderr, "* Marked up Applesingle data fork at offset %lu and size %lu. End is %lu.\n", offset, length, d->bodyend); #endif break; case 2: /* Resource fork */ if (length) { if (check_length(d, + offset + length) != OK) { #ifdef DEBUG if (edebug) { fprintf(stderr, "* get_applesingle_binary: resource fork: short file %lu.\n", d->offset); fprintf(stderr, "* get_applesingle_binary: suggested offset: %lu suggested length: %lu\n", offset, length); fprintf(stderr, "* get_applesingle_binary: bodystart %lu end %lu\n", d->bodystart, d->bodyend); } #endif return(NOK); } #ifdef DEBUG if (edebug) fprintf(stderr, "* Marked up Applesingle resource fork at offset %lu and size %lu. End is %lu.\n", offset, length, d->bodyend); #endif r = (struct data *)Yalloc(sizeof(struct data)); /* Copied for now */ append_data(r, d->contents + d->bodystart + offset, length, pz); r->applefile = ARESOURCE; r->encoding = EBINARY; d->applefile = AFILE; } break; case 3: /* Name */ if (check_length(d, offset + length) != OK) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: name: short file %lu.\n", d->offset); #endif return(NOK); } m->sd->name = (char *)Yalloc(length + 1); bcopy(d->contents + d->bodystart + offset, m->sd->name, length); break; case 4: /* Comment */ /* Ignore */ break; case 5: /* BW icon */ /* Ignore */ break; case 6: /* Color icon */ /* Ignore */ break; case 8: /* dates */ /* Ignore */ break; case 9: /* Finder info */ if (check_length(d, offset + length) != OK) { #ifdef DEBUG if (edebug) fprintf(stderr, "* get_applesingle_binary: finder info: short file %lu.\n", d->offset); #endif return(NOK); } if (m->sd->appletype == NULL) m->sd->appletype = (char *)Yalloc(9); bcopy(d->contents + d->bodystart + offset, m->sd->appletype, 8); break; case 10: /* Mac file info */ /* Ignore */ break; case 11: /* ProDOS file info */ /* Ignore */ break; case 12: /* MS-DOS file info */ /* Ignore */ break; case 13: /* AFP short name */ /* Ignore */ break; case 14: /* AFP file info */ /* Ignore */ break; case 15: /* AFP directory id */ /* Ignore */ break; default: /* Unknown entry ID */ return(NOK); break; } } if (dlength != 0) { d->bodystart = doffset; d->bodyend = doffset + dlength; if ((d->type = (char *)confextr("APPLEFILE", d->appletype, NULL)) == NULL) if ((d->type = (char *)confextr("APPLEFILE", "DEFAULT", NULL)) == NULL) d->type = NEWSTR("APPLICATION"); } else { free_data(d); d = NULL; } m->td = d; d->next = r; return(OK); } int put_applesingle(struct message *m) { struct data *target; struct data *data; struct data *resource; int i; unsigned long offset, dlength, nlength, rlength, flength; #ifdef DEBUG if (edebug) fprintf(stderr, "* put_applesingle()..."); #endif target = (struct data *)Yalloc(sizeof(struct data)); target->encoding = EBINARY; macify_filename(m); if ((data = m->td) != NULL) data->offset = data->bodystart; else return(NOK); target->type = data->type; if ((resource = m->td->next) != NULL) resource->offset = resource->bodystart; /* Add magic number */ append_data(target, makelong(0x00051600, 4), 4, pz); /* Add version */ append_data(target, makelong(0x00020000, 4), 4, pz); /* Add filler */ for (i = 0; i < 4; i++) append_data(target, makelong(0x00000000, 4), 4, pz); /* Add entries */ append_data(target, makelong(0x0004, 2), 2, pz); /* Add entries, Offset = 26 */ /* Name */ offset = 74; append_data(target, makelong(0x00000003, 4), 4, pz); append_data(target, makelong(offset, 4), 4, pz); nlength = strlen(m->sd->name); append_data(target, makelong(nlength, 4), 4, pz); offset += nlength; /* Finder info */ append_data(target, makelong(0x00000009, 4), 4, pz); append_data(target, makelong(offset, 4), 4, pz); flength = 32; append_data(target, makelong(flength, 4), 4, pz); offset += flength; /* Data fork */ append_data(target, makelong(0x00000001, 4), 4, pz); append_data(target, makelong(offset, 4), 4, pz); dlength = data->bodyend - data->bodystart; append_data(target, makelong(dlength, 4), 4, pz); offset += dlength; /* Resource fork */ append_data(target, makelong(0x00000002, 4), 4, pz); append_data(target, makelong(offset, 4), 4, pz); rlength = resource->bodyend - resource->bodystart; append_data(target, makelong(rlength, 4), 4, pz); /* Add name */ append_data(target, m->sd->name, nlength, pz); /* Add finder info */ append_data(target, m->sd->appletype, 8, pz); for (i = 0; i < 6; i++) append_data(target, makelong(0x00000000, 4), 4, pz); /* Add data fork */ append_data(target, data->contents + data->bodystart, dlength, pz); /* Add resource fork */ append_data(target, resource->contents + resource->bodystart, rlength, pz); m->td = target; m->sd->applefile = ASINGLE; m->sd->type = NEWSTR("APPLESINGLE"); m->td->encoding = EBINARY; #ifdef DEBUG if (edebug) fprintf(stderr, "OK.\n"); #endif return(OK); } /* * Check for AppleSingle/AppleDouble */ void check_as_ad(struct message *m) { struct data *d; char typer[5]; long ltyper; d = m->td; if (d->offset + 4 >= d->end) return; bzero(typer, 5); bcopy(d->contents + d->offset, typer, 4); ltyper = strtol(typer, NULL, 16); if (0x0051607 == ltyper) m->sd->applefile = ADOUBLE; if (0x0051600 == ltyper) m->sd->applefile = ASINGLE; }