/*
**
** 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 <assert.h>
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;
}
syntax highlighted by Code2HTML, v. 0.9.1