📄 apple.c
字号:
static intget_es_dir(hname, dname, s_entry, ret) char *hname; /* whole path */ char *dname; /* this dir name */ dir_ent *s_entry; /* directory entry */ int ret;{ es_FileInfo *einfo; /* EtherShare info struct */ us_FileInfo *uinfo; /* UShare info struct */ char info[ES_INFO_SIZE]; /* finderinfo buffer */ int num = -1; /* bytes read */ hfsdirent *hfs_ent = s_entry->hfs_ent; /* * the EtherShare and UShare file layout is the same, but they store * finderinfo differently */ einfo = (es_FileInfo *) info; uinfo = (us_FileInfo *) info; num = read_info_file(hname, info, sizeof(info)); /* check finder info for EtherShare finderinfo */ if (num >= sizeof(es_FileInfo) && d_getl(einfo->magic) == ES_MAGIC && d_getw(einfo->version) == ES_VERSION) { set_Dinfo(einfo->finderinfo, hfs_ent); } else if (num >= sizeof(us_FileInfo)) { /* * UShare has no magic number, so we assume that this is a valid * info/resource file ... */ set_Dinfo(uinfo->finderinfo, hfs_ent); } else { /* failed to open/read finderinfo - so try afpfile mapping */ if (verbose > 2) { fprintf(stderr, "warning: %s doesn't appear to be a %s file\n", s_entry->whole_name, hfs_types[ret].desc); } ret = get_none_dir(hname, dname, s_entry, TYPE_NONE); return (ret); } /* set name */ hstrncpy((unsigned char *) (hfs_ent->name), dname, HFS_MAX_FLEN); return (ret);}/* * get_es_info: get EtherShare/UShare finderinfo for a file * * based on code from Jens-Uwe Mager (jum@helios.de) and Phil Sylvester * <psylvstr@interaccess.com> */static intget_es_info(hname, dname, s_entry, ret) char *hname; /* whole path */ char *dname; /* this dir name */ dir_ent *s_entry; /* directory entry */ int ret;{ es_FileInfo *einfo; /* EtherShare info struct */ us_FileInfo *uinfo; /* UShare info struct */ char info[ES_INFO_SIZE]; /* finderinfo buffer */ int num = -1; /* bytes read */ hfsdirent *hfs_ent = s_entry->hfs_ent; dir_ent *s_entry1; /* * the EtherShare and UShare file layout is the same, but they store * finderinfo differently */ einfo = (es_FileInfo *) info; uinfo = (us_FileInfo *) info; num = read_info_file(hname, info, sizeof(info)); /* check finder info for EtherShare finderinfo */ if (num >= sizeof(es_FileInfo) && d_getl(einfo->magic) == ES_MAGIC && d_getw(einfo->version) == ES_VERSION) { set_Finfo(einfo->finderinfo, hfs_ent); /* * set create date - modified date set from the Unix * data fork date */ hfs_ent->crdate = d_getl(einfo->createTime); } else if (num >= sizeof(us_FileInfo)) { /* * UShare has no magic number, so we assume that this is a valid * info/resource file ... */ set_Finfo(uinfo->finderinfo, hfs_ent); /* set create and modified date - if they exist */ if (uinfo->ctime) hfs_ent->crdate = d_getl(uinfo->ctime); if (uinfo->mtime) hfs_ent->mddate = d_getl(uinfo->mtime); } else { /* failed to open/read finderinfo - so try afpfile mapping */ if (verbose > 2) { fprintf(stderr, "warning: %s doesn't appear to be a %s file\n", s_entry->whole_name, hfs_types[ret].desc); } ret = get_none_info(hname, dname, s_entry, TYPE_NONE); return (ret); } /* this should exist ... */ if ((s_entry1 = s_entry->assoc) == NULL) perr("TYPE_ESH error - shouldn't happen!"); /* set name */ hstrncpy((unsigned char *) (hfs_ent->name), dname, HFS_MAX_FLEN); /* real rsrc file starts ES_INFO_SIZE bytes into the file */ if (s_entry1->size <= ES_INFO_SIZE) { s_entry1->size = 0; hfs_ent->u.file.rsize = 0; } else { s_entry1->size -= ES_INFO_SIZE; hfs_ent->u.file.rsize = s_entry1->size; s_entry1->hfs_off = ES_INFO_SIZE; } set_733((char *) s_entry1->isorec.size, s_entry1->size); return (ret);}/* * calc_crc() -- * Compute the MacBinary II-style CRC for the data pointed to by p, with the * crc seeded to seed. * * Modified by Jim Van Verth to use the magic array for efficiency. */#ifdef __used__#ifdef PROTOTYPESstatic unsigned shortcalc_mb_crc(unsigned char *p, long len, unsigned short seed)#elsestatic unsigned shortcalc_mb_crc(p, len, seed) unsigned char *p; long len; unsigned short seed;#endif{ unsigned short hold; /* crc computed so far */ long i; /* index into data */ hold = seed; /* start with seed */ for (i = 0; i < len; i++, p++) { hold ^= (*p << 8); hold = (hold << 8) ^ mb_magic[(unsigned char) (hold >> 8)]; } return (hold);}/* calc_mb_crc() */#endif /* __used__ */static intget_mb_info(hname, dname, s_entry, ret) char *hname; /* whole path */ char *dname; /* this dir name */ dir_ent *s_entry; /* directory entry */ int ret;{ mb_info *info; /* finderinfo struct */ char *c; char *t; hfsdirent *hfs_ent; dir_ent *s_entry1; int i;#ifdef TEST_CODE unsigned short crc_file, crc_calc;#endif info = (mb_info *) p_buf; /* * routine called twice for each file - first to check that it is a * valid MacBinary file, second to fill in the HFS info. p_buf holds * the required raw data and it *should* remain the same between the * two calls */ if (s_entry == 0) { /* * test that the CRC is OK - not set for MacBinary I files (and * incorrect in some MacBinary II files!). If this fails, then * perform some other checks */#ifdef TEST_CODE /* leave this out for the time being ... */ if (p_num >= MB_SIZE && info->version == 0 && info->zero1 == 0) { crc_calc = calc_mb_crc((unsigned char *) info, 124, 0); crc_file = d_getw(info->crc);#ifdef DEBUG fprintf(stderr, "%s: file %d, calc %d\n", hname, crc_file, crc_calc);#endif /* DEBUG */ if (crc_file == crc_calc) return (ret); }#endif /* TEST_CODE */ /* * check some of the fields for a valid MacBinary file not * zero1 and zero2 SHOULD be zero - but some files incorrect *//* if (p_num < MB_SIZE || info->nlen > 63 || info->zero2 || */ if (p_num < MB_SIZE || info->zero1 || info->zero2 || info->nlen > 63 || info->version || info->nlen == 0 || *info->name == 0) return (TYPE_NONE); /* check that the filename is OKish */ for (i = 0; i < info->nlen; i++) if (info->name[i] == 0) return (TYPE_NONE); /* check CREATOR and TYPE are valid */ for (i = 0; i < 4; i++) if (info->type[i] == 0 || info->auth[i] == 0) return (TYPE_NONE); } else { /* we have a vaild MacBinary file, so fill in the bits */ /* this should exist ... */ if ((s_entry1 = s_entry->assoc) == NULL) perr("TYPE_MBIN error - shouldn't happen!"); hfs_ent = s_entry->hfs_ent; /* type and creator from finder info */ t = (char *) (info->type); c = (char *) (info->auth); set_ct(hfs_ent, c, t); /* finder flags */ hfs_ent->fdflags = ((info->flags << 8) & 0xff00) | info->flags2; if (icon_pos) { hfs_ent->fdlocation.v = d_getw((unsigned char *) info->icon_vert); hfs_ent->fdlocation.h = d_getw((unsigned char *) info->icon_horiz); } else { /* * clear HFS_FNDR_HASBEENINITED to have tidy desktop ?? */ hfs_ent->fdflags &= 0xfeff; } /* * set created/modified dates - these date should have already * been set from the Unix data fork dates. The finderinfo dates * are in Mac format - but we have to convert them back to Unix * for the time being */ hfs_ent->crdate = d_toutime(d_getl(info->cdate)); hfs_ent->mddate = d_toutime(d_getl(info->mdate)); /* set name */ hstrncpy((unsigned char *) (hfs_ent->name), (char *) (info->name), MIN(HFS_MAX_FLEN, info->nlen)); /* set correct fork sizes */ hfs_ent->u.file.dsize = d_getl(info->dflen); hfs_ent->u.file.rsize = d_getl(info->rflen); /* update directory entries for data fork */ s_entry->size = hfs_ent->u.file.dsize; s_entry->hfs_off = MB_SIZE; set_733((char *) s_entry->isorec.size, s_entry->size); /* * real rsrc file starts after data fork (must be a multiple of * MB_SIZE) */ s_entry1->size = hfs_ent->u.file.rsize; s_entry1->hfs_off = MB_SIZE + ROUND_UP(hfs_ent->u.file.dsize, MB_SIZE); set_733((char *) s_entry1->isorec.size, s_entry1->size); } return (ret);}/* * get_dbl_dir: get Apple double finderinfo for a directory * * Based on code from cvt2cap.c (c) May 1988, Paul Campbell */static intget_dbl_dir(hname, dname, s_entry, ret) char *hname; /* whole path */ char *dname; /* this dir name */ dir_ent *s_entry; /* directory entry */ int ret;{ FileInfo info; /* finderinfo struct */ a_hdr *hp; a_entry *ep; int num = -1; /* bytes read */ int nentries; FILE *fp; hfsdirent *hfs_ent = s_entry->hfs_ent; char name[64]; int i; int fail = 0; int len = 0; hp = (a_hdr *) p_buf; memset(hp, 0, A_HDR_SIZE); memset(name, 0, sizeof(name)); /* open and read the info/rsrc file (it's the same file) */ if ((fp = fopen(hname, "rb")) != NULL) num = fread(hp, 1, A_HDR_SIZE, fp); /* * check finder info is OK - some Netatalk files don't have magic * or version set - ignore if it's a netatalk file */ if (num == A_HDR_SIZE && ((ret == TYPE_NETA) || (d_getl(hp->magic) == APPLE_DOUBLE && (d_getl(hp->version) == A_VERSION1 || d_getl(hp->version) == A_VERSION2)))) { /* read TOC of the AppleDouble file */ nentries = (int) d_getw(hp->nentries); if (fread(hp->entries, A_ENTRY_SIZE, nentries, fp) < 1) { fail = 1; nentries = 0; } /* extract what is needed */ for (i = 0, ep = hp->entries; i < nentries; i++, ep++) { switch ((int)d_getl(ep->id)) { case ID_FINDER: /* get the finder info */ fseek(fp, d_getl(ep->offset), 0); if (fread(&info, d_getl(ep->length), 1, fp) < 1) { fail = 1; } break; case ID_NAME: /* get Mac file name */ fseek(fp, d_getl(ep->offset), 0); if (fread(name, d_getl(ep->length), 1, fp) < 1) *name = '\0'; len = d_getl(ep->length); break; default: break; } } fclose(fp); /* skip this if we had a problem */ if (!fail) { set_Dinfo(info.finderinfo, hfs_ent); /* use stored name if it exists */ if (*name) { /* * In some cases the name is stored in the * Pascal string format - first char is the * length, the rest is the actual string. * The following *should* be OK */ if (len == 32 && (int) name[0] < 32) { cstrncpy(hfs_ent->name, &name[1], MIN(name[0], HFS_MAX_FLEN)); } else { cstrncpy(hfs_ent->name, name, HFS_MAX_FLEN); } } else { hstrncpy((unsigned char *) (hfs_ent->name), dname, HFS_MAX_FLEN); } } } else { /* failed to open/read finderinfo */ fail = 1; if (fp) fclose(fp); } if (fail) { /* problem with the file - try mapping/magic */ if (verbose > 2) { fprintf(stderr, "warning: %s doesn't appear to be a %s file\n", s_entry->whole_name, hfs_types[ret].desc); } ret = get_none_dir(hname, dname, s_entry, TYPE_NONE); } return (ret);}/* * get_dbl_info: get Apple double finderinfo for a file * * Based on code from cvt2cap.c (c) May 1988, Paul Campbell */static intget_dbl_info(hname, dname, s_entry, ret) char *hname; /* whole path */ char *dname; /* this dir name */ dir_ent *s_entry; /* directory entry */ int ret;{ FileInfo info; /* finderinfo struct */ a_hdr *hp; a_entry *ep; int num = -1; /* bytes read */ int nentries; FILE *fp; hfsdirent *hfs_ent = s_entry->hfs_ent; dir_ent *s_entry1; char name[64]; int i; int fail = 0; int len = 0; hp = (a_hdr *) p_buf; memset(hp, 0, A_HDR_SIZE); memset(name, 0, sizeof(name)); /* get the rsrc file info - should exist ... */ if ((s_entry1 = s_entry->assoc) == NULL) perr("TYPE_DBL error - shouldn't happen!"); /* open and read the info/rsrc file (it's the same file) */ if ((fp = fopen(hname, "rb")) != NULL) num = fread(hp, 1, A_HDR_SIZE, fp); /* * check finder info is OK - some Netatalk files don't have magic * or version set - ignore if it's a netatalk file */ if (num == A_HDR_SIZE && ((ret == TYPE_NETA) || (d_getl(hp->magic) == APPLE_DOUBLE && (d_getl(hp->version) == A_VERSION1 || d_getl(hp->version) == A_VERSION2)))) { /* read TOC of the AppleDouble file */ nentries = (int) d_getw(hp->nentries); if (fread(hp->entries, A_ENTRY_SIZE, nentries, fp) < 1) { fail = 1; nentries = 0; } /* extract what is needed */ for (i = 0, ep = hp->entries; i < nentries; i++, ep++) { switch ((int)d_getl(ep->id)) { case ID_FINDER: /* get the finder info */ fseek(fp, d_getl(ep->offset), 0); if (fread(&info, d_getl(ep->length), 1, fp) < 1) { fail = 1; } break; case ID_RESOURCE: /* set the offset and correct rsrc fork size */ s_entry1->size = d_getl(ep->length); hfs_ent->u.file.rsize = s_entry1->size; /* offset to start of real rsrc fork */ s_entry1->hfs_off = d_getl(ep->offset); set_733((char *) s_entry1->isorec.size, s_entry1->size); break; case ID_NAME: /* get Mac file name */ fseek(fp, d_getl(ep->offset), 0); if (fread(name, d_getl(ep->length), 1, fp) < 1) *name = '\0'; len = d_getl(ep->length); break; default: break; } } fclose(fp); /* skip this if we had a problem */ if (!fail) { set_Finfo(info.finderinfo, hfs_ent); /* use stored name if it exists */ if (*name) { /* * In some cases the name is stored in the * Pascal string format - first char is the * length, the rest is the actual string. * The following *should* be OK */ if (len == 32 && (int) name[0] < 32) { cstrncpy(hfs_ent->name, &name[1], MIN(name[0], HFS_MAX_FLEN)); } else { cstrncpy(hfs_ent->name, name, HFS_MAX_FLEN); } } else { hstrncpy((unsigned char *) (hfs_ent->name), dname, HFS_MAX_FLEN); } } } else { /* failed to open/read finderinfo */ fail = 1; if (fp) fclose(fp); } if (fail) { /* problem with the file - try mapping/magic */ if (verbose > 2) { fprintf(stderr, "warning: %s doesn't appear to be a %s file\n", s_entry->whole_name, hfs_types[ret].desc); } ret = get_none_info(hname, dname, s_entry, TYPE_NONE); } return (ret);}/* * get_sgl_info: get Apple single finderinfo for a file * * Based on code from cvt2cap.c (c) May 1988, Paul Campbell */static intget_sgl_info(hname, dname, s_entry, ret) char *hname; /* whole path */ char *dname; /* this dir name */ dir_ent *s_entry; /* directory entry */ int ret;{ FileInfo *info = 0; /* finderinfo struct */ a_hdr *hp; static a_entry *entries; a_entry *ep; int nentries; hfsdirent *hfs_ent; dir_ent *s_entry1; char name[64]; int i; int len = 0; /* * routine called twice for each file * - first to check that it is a valid * MacBinary file, second to fill in the HFS info. * p_buf holds the required * raw data and it *should* remain the same between the two calls */ hp = (a_hdr *) p_buf; if (s_entry == 0) { if (p_num < A_HDR_SIZE || d_getl(hp->magic) != APPLE_SINGLE || (d_getl(hp->version) != A_VERSION1 && d_getl(hp->version) != A_VERSION1)) return (TYPE_NONE); /* check we have TOC for the AppleSingle file */ nentries = (int) d_getw(hp->nentries); if (p_num < (A_HDR_SIZE + nentries * A_ENTRY_SIZE)) return (TYPE_NONE); /* save the TOC */ entries = (a_entry *) e_malloc(nentries * A_ENTRY_SIZE); memcpy(entries, (p_buf + A_HDR_SIZE), nentries * A_ENTRY_SIZE); } else { /* have a vaild AppleSingle File */ memset(name, 0, sizeof(name)); /* get the rsrc file info - should exist ... */ if ((s_entry1 = s_entry->assoc) == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -