📄 apple.c
字号:
perr("TYPE_SGL error - shouldn't happen!"); hfs_ent = s_entry->hfs_ent; nentries = (int) d_getw(hp->nentries); /* extract what is needed */ for (i = 0, ep = entries; i < nentries; i++, ep++) { switch ((int)d_getl(ep->id)) { case ID_FINDER: /* get the finder info */ info = (FileInfo *) (p_buf + d_getl(ep->offset)); break; case ID_DATA: /* set the offset and correct data fork size */ hfs_ent->u.file.dsize = s_entry->size = d_getl(ep->length); /* offset to start of real data fork */ s_entry->hfs_off = d_getl(ep->offset); set_733((char *) s_entry->isorec.size, s_entry->size); break; case ID_RESOURCE: /* set the offset and correct rsrc fork size */ hfs_ent->u.file.rsize = s_entry1->size = d_getl(ep->length); /* 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: strncpy(name, (p_buf + d_getl(ep->offset)), d_getl(ep->length)); len = d_getl(ep->length); break; default: break; } } free(entries); if (info == NULL) { /* * 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); } 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); } } return (ret);}/* * get_hfs_fe_info: read in the whole finderinfo for a PC Exchange * directory - saves on reading this many times for each file. * * Based of information provided by Mark Weinstein <mrwesq@earthlink.net> * * Note: the FINDER.DAT file layout depends on the FAT cluster size * therefore, files should only be read directly from the FAT media * * Only tested with PC Exchange v2.1 - don't know if it will work * with v2.2 and above. */static struct hfs_info *get_hfs_fe_info(hfs_info, name) struct hfs_info *hfs_info; char *name;{ FILE *fp; int fe_num, fe_pad; fe_info info; int c = 0; struct hfs_info *hfs_info1 = NULL; char keyname[12]; char *s, *e, *k; int i; if ((fp = fopen(name, "rb")) == NULL) return (NULL); /* * no longer attempt to find out FAT cluster * - rely on command line parameter */ if (afe_size <= 0) return (NULL); fe_num = afe_size / FE_SIZE; fe_pad = afe_size % FE_SIZE; while (fread(&info, 1, FE_SIZE, fp) != 0) { /* the Mac name may be NULL - so ignore this entry */ if (info.nlen != 0) { hfs_info1 = (struct hfs_info *)e_malloc(sizeof(struct hfs_info)); /* add this entry to the list */ hfs_info1->next = hfs_info; hfs_info = hfs_info1; /* * get the bits we need * - ignore [cm]time for the moment */ cstrncpy(hfs_info->name, (char *) (info.name), info.nlen); memcpy(hfs_info->finderinfo, info.finderinfo, INFOLEN); s = (char *) (info.sname); e = (char *) (info.ext); k = keyname; /* * short (Unix) name is stored in PC format, * so needs to be mangled a bit */ /* name part */ for (i = 0; i < 8; i++, s++, k++) { if (*s == ' ') break; else *k = *s; } /* extension - if it exists */ if (strncmp((const char *) (info.ext), " ", 3)) { *k = '.'; k++; for (i = 0; i < 3; i++, e++, k++) { if (*e == ' ') break; else *k = *e; } } *k = '\0'; hfs_info1->keyname = strdup(keyname); } /* * each record is FE_SIZE long, and there are FE_NUM * per each "cluster size", so we may need to skip the padding */ if (++c == fe_num) { c = 0; fseek(fp, fe_pad, 1); } } fclose(fp); return (hfs_info);}/* * get_hfs_sgi_info: read in the whole finderinfo for a SGI (XINET) * directory - saves on reading this many times for each * file. */static struct hfs_info *get_hfs_sgi_info(hfs_info, name) struct hfs_info *hfs_info; char *name;{ FILE *fp; sgi_info info; struct hfs_info *hfs_info1 = NULL; if ((fp = fopen(name, "rb")) == NULL) return (NULL); while (fread(&info, 1, SGI_SIZE, fp) != 0) { hfs_info1 = (struct hfs_info *)e_malloc(sizeof(struct hfs_info)); /* add this entry to the list */ hfs_info1->next = hfs_info; hfs_info = hfs_info1; /* get the bits we need - ignore [cm]time for the moment */ cstrncpy(hfs_info->name, (char *)info.name, HFS_MAX_FLEN); memcpy(hfs_info->finderinfo, info.finderinfo, INFOLEN); /* use the HFS name as the key */ hfs_info1->keyname = hfs_info->name; } fclose(fp); return (hfs_info);}/* * del_hfs_info: delete the info list and recover memory */voiddel_hfs_info(hfs_info) struct hfs_info *hfs_info;{ struct hfs_info *hfs_info1; while (hfs_info) { hfs_info1 = hfs_info; hfs_info = hfs_info->next; /* key may be the same as the HFS name - so don't free it */ *hfs_info1->name = '\0'; if (*hfs_info1->keyname) free(hfs_info1->keyname); free(hfs_info1); }}/* * match_key: find the correct hfs_ent using the Unix filename * as the key */static struct hfs_info *match_key(hfs_info, key) struct hfs_info *hfs_info; char *key;{ while (hfs_info) { if (!strcasecmp(key, hfs_info->keyname)) return (hfs_info); hfs_info = hfs_info->next; } return (NULL);}/* * get_fe_dir: get PC Exchange directory name * * base on probing with od ... */static intget_fe_dir(hname, dname, s_entry, ret) char *hname; /* whole path */ char *dname; /* this dir name */ dir_ent *s_entry; /* directory entry */ int ret;{ struct hfs_info *hfs_info; hfsdirent *hfs_ent = s_entry->hfs_ent; /* cached finderinfo stored with parent directory */ hfs_info = s_entry->filedir->hfs_info; /* if we have no cache, then make one and store it */ if (hfs_info == NULL) { if ((hfs_info = get_hfs_fe_info(hfs_info, hname)) == NULL) ret = TYPE_NONE; else s_entry->filedir->hfs_info = hfs_info; } if (ret != TYPE_NONE) { /* see if we can find the details of this file */ if ((hfs_info = match_key(hfs_info, dname)) != NULL) { strcpy(hfs_ent->name, hfs_info->name); set_Dinfo(hfs_info->finderinfo, hfs_ent); return (ret); } } /* can't find the entry, so use the Unix name */ hstrncpy((unsigned char *)(hfs_ent->name), dname, HFS_MAX_FLEN); return (TYPE_NONE);}/* * get_fe_info: get PC Exchange file details. * * base on probing with od and details from Mark Weinstein * <mrwesq@earthlink.net> */static intget_fe_info(hname, dname, s_entry, ret) char *hname; /* whole path */ char *dname; /* this dir name */ dir_ent *s_entry; /* directory entry */ int ret;{ struct hfs_info *hfs_info; hfsdirent *hfs_ent = s_entry->hfs_ent;; /* cached finderinfo stored with parent directory */ hfs_info = s_entry->filedir->hfs_info; /* if we have no cache, then make one and store it */ if (hfs_info == NULL) { if ((hfs_info = get_hfs_fe_info(hfs_info, hname)) == NULL) ret = TYPE_NONE; else s_entry->filedir->hfs_info = hfs_info; } if (ret != TYPE_NONE) { char *dn = dname;#ifdef _WIN32_TEST /* * may have a problem here - v2.2 has long filenames, * but we need to key on the short filename, * so we need do go a bit of win32 stuff * ... */ char sname[1024], lname[1024]; cygwin32_conv_to_full_win32_path(s_entry->whole_name, lname); if (GetShortPathName(lname, sname, sizeof(sname))) { if (dn = strrchr(sname, '\\')) dn++; else dn = sname; }#endif /* _WIN32 */ /* see if we can find the details of this file */ if ((hfs_info = match_key(hfs_info, dn)) != NULL) { strcpy(hfs_ent->name, hfs_info->name); set_Finfo(hfs_info->finderinfo, hfs_ent); return (ret); } } /* no entry found - use extension 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 (TYPE_NONE);}/* * get_sgi_dir: get SGI (XINET) HFS directory name * * base on probing with od ... */static intget_sgi_dir(hname, dname, s_entry, ret) char *hname; /* whole path */ char *dname; /* this dir name */ dir_ent *s_entry; /* directory entry */ int ret;{ struct hfs_info *hfs_info; hfsdirent *hfs_ent = s_entry->hfs_ent; /* cached finderinfo stored with parent directory */ hfs_info = s_entry->filedir->hfs_info; /* if we haven't got a cache, then make one */ if (hfs_info == NULL) { if ((hfs_info = get_hfs_sgi_info(hfs_info, hname)) == NULL) ret = TYPE_NONE; else s_entry->filedir->hfs_info = hfs_info; } /* find the matching entry in the cache */ if (ret != TYPE_NONE) { /* key is (hopefully) the real Mac name */ cstrncpy(tmp, dname, strlen(dname)); if ((hfs_info = match_key(hfs_info, tmp)) != NULL) { strcpy(hfs_ent->name, hfs_info->name); set_Dinfo(hfs_info->finderinfo, hfs_ent); return (ret); } } /* no entry found - use Unix name */ hstrncpy((unsigned char *)(hfs_ent->name), dname, HFS_MAX_FLEN); return (TYPE_NONE);}/* * get_sgi_info: get SGI (XINET) HFS finder info * * base on probing with od ... */static intget_sgi_info(hname, dname, s_entry, ret) char *hname; /* whole path */ char *dname; /* this dir name */ dir_ent *s_entry; /* directory entry */ int ret;{ struct hfs_info *hfs_info; hfsdirent *hfs_ent = s_entry->hfs_ent; /* cached finderinfo stored with parent directory */ hfs_info = s_entry->filedir->hfs_info; /* if we haven't got a cache, then make one */ if (hfs_info == NULL) { if ((hfs_info = get_hfs_sgi_info(hfs_info, hname)) == NULL) ret = TYPE_NONE; else s_entry->filedir->hfs_info = hfs_info; } if (ret != TYPE_NONE) { /* * tmp is the same as hname here, but we don't need hname * anymore in this function ... see if we can find the * details of this file using the Unix name as the key */ cstrncpy(tmp, dname, strlen(dname)); if ((hfs_info = match_key(hfs_info, tmp)) != NULL) { strcpy(hfs_ent->name, hfs_info->name); set_Dinfo(hfs_info->finderinfo, hfs_ent); return (ret); } } /* no entry found, so try file extension */ 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 (TYPE_NONE);}/* * get_sfm_info: get SFM finderinfo for a file */static byte sfm_magic[4] = {0x41, 0x46, 0x50, 0x00};static byte sfm_version[4] = {0x00, 0x00, 0x01, 0x00};static intget_sfm_info(hname, dname, s_entry, ret) char *hname; /* whole path */ char *dname; /* this dir name */ dir_ent *s_entry; /* directory entry */ int ret;{ sfm_info info; /* finderinfo struct */ int num = -1;/* bytes read */ hfsdirent *hfs_ent = s_entry->hfs_ent; num = read_info_file(hname, &info, sizeof(info)); /* check finder info is OK */ if (num == sizeof(info) && !strncmp((char *)info.afpi_Signature, (char *)sfm_magic, 4) && !strncmp((char *)info.afpi_Version, (char *)sfm_version, 4)) { /* use Unix name */ hstrncpy((unsigned char *)(hfs_ent->name), dname, HFS_MAX_FLEN); set_Finfo(info.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_info(hname, dname, s_entry, TYPE_NONE); } return (ret);}/* * get_hfs_itype: get the type of HFS info for a file */static intget_hfs_itype(wname, dname, htmp) char *wname; char *dname; char *htmp;{ int wlen, i; wlen = strlen(wname) - strlen(dname); /* search through the known types looking for matches */ for (i = 1; i < hfs_num; i++) { /* skip the ones that we don't care about */ if ((hfs_types[i].flags & PROBE) || *(hfs_types[i].info) == TYPE_NONE) { continue; } strcpy(htmp, wname); /* append or insert finderinfo filename part */ if (hfs_types[i].flags & APPEND) strcat(htmp, hfs_types[i].info); else sprintf(htmp + wlen, "%s%s", hfs_types[i].info, (hfs_types[i].flags & NOPEND) ? "" : dname); /* hack time ... Netatalk is a special case ... */ if (i == TYPE_NETA) { strcpy(htmp, wname); strcat(htmp, "/.AppleDouble/.Parent"); } if (!access(htmp, R_OK)) return (hfs_types[i].type); } return (TYPE_NONE);}/* * set_root_info: set the root folder hfs_ent from given file */voidset_root_info(name) char *name;{ dir_ent *s_entry; hfsdirent *hfs_ent; int i; s_entry = root->self; hfs_ent = (hfsdirent *) e_malloc(sizeof(hfsdirent)); memset(hfs_ent, 0, sizeof(hfsdirent)); /* make sure root has a valid hfs_ent */ s_entry->hfs_ent = root->hfs_ent = hfs_ent; /* search for correct type of root info data */ for (i=1; i<hfs_num; i++) { if ((hfs_types[i].flags & PROBE) || (hfs_types[i].get_info == get_none_info)) continue; if ((*(hfs_types[i].get_dir))(name, "", s_entry, i) == i) return; }}/* * get_hfs_dir: set the HFS directory name */intget_hfs_dir(wname, dname, s_entry) char *wname; char *dname; dir_ent *s_entry;{ int type; /* get the HFS file type from the info file (if it exists) */ type = get_hfs_itype(wname, dname, tmp); /* try to get the required info */ type = (*(hfs_types[type].get_dir)) (tmp, dname, s_entry, type); return (type);}/* * get_hfs_info: set the HFS info for a file */int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -