BLLookupFileIDOnMount.c [plain text]
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <hfs/hfs_format.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/attr.h>
#include <System/sys/fsgetpath.h>
#include "bless.h"
#include "bless_private.h"
struct cataloginfo {
attrreference_t name;
fsid_t volid;
fsobj_id_t objectid;
fsobj_id_t parentid;
char namebuffer[NAME_MAX];
};
struct cataloginforeturn {
uint32_t length;
struct cataloginfo c;
};
static int lookupIDOnVolID(uint32_t volid, uint32_t fileID, char *out);
int BLLookupFileIDOnMount(BLContextPtr context, const char *mount, uint32_t fileID, char *out) {
struct attrlist alist;
struct cataloginforeturn catinfo;
int err;
uint32_t volid;
char relpath[MAXPATHLEN];
out[0] = '\0';
if (fileID < kHFSRootFolderID) {
return ENOENT;
}
alist.bitmapcount = 5;
alist.commonattr = ATTR_CMN_NAME | ATTR_CMN_FSID | ATTR_CMN_OBJID | ATTR_CMN_PAROBJID;
alist.volattr = 0;
alist.dirattr = 0;
alist.fileattr = 0;
alist.forkattr = 0;
err = getattrlist(mount, &alist, &catinfo, sizeof(catinfo), 0);
if (err) {
return errno;
}
volid = (uint32_t)catinfo.c.volid.val[0];
err = lookupIDOnVolID(volid, fileID, relpath);
if (err) {
return err;
}
if(strcmp(mount, "/")) {
snprintf(out, MAXPATHLEN, "%s/%s", mount, relpath);
} else {
snprintf(out, MAXPATHLEN, "/%s", relpath);
}
return 0;
}
int BLLookupFileIDOnMount64(BLContextPtr context, const char *mountpoint, uint64_t fileID, char *out, int bufsize)
{
int err;
struct statfs sfs;
if (statfs(mountpoint, &sfs) < 0) {
return errno;
}
err = fsgetpath(out, bufsize, &sfs.f_fsid, fileID);
if (err < 0) return errno;
return 0;
}
static int lookupIDOnVolID(uint32_t volid, uint32_t fileID, char *out) {
char *bp;
uint32_t dirID = fileID;
char volpath[MAXPATHLEN];
struct attrlist alist;
struct cataloginforeturn catinfo;
int err;
out[0] = '\0';
if (fileID <= 2) {
return 0;
}
bp = &(out[MAXPATHLEN-1]);
*bp = '\0';
while(dirID != kHFSRootFolderID) {
char *nameptr;
size_t namelen;
sprintf(volpath, "/.vol/%u/%u", volid, dirID);
alist.bitmapcount = 5;
alist.commonattr = ATTR_CMN_NAME | ATTR_CMN_FSID | ATTR_CMN_OBJID | ATTR_CMN_PAROBJID;
alist.volattr = 0;
alist.dirattr = 0;
alist.fileattr = 0;
alist.forkattr = 0;
err = getattrlist(volpath, &alist, &catinfo, sizeof(catinfo), 0);
if (err) {
return errno;
}
dirID = (uint32_t)catinfo.c.parentid.fid_objno;
nameptr = (char *)(&catinfo.c.name) + catinfo.c.name.attr_dataoffset;
namelen = strlen(nameptr);
if (bp - out < namelen) {
return ENAMETOOLONG;
}
bp -= namelen;
strncpy(bp, nameptr, namelen);
if (dirID != kHFSRootFolderID ) {
if (!(bp > out)) {
return ENAMETOOLONG;
}
bp--;
*bp = '/';
}
}
memmove(out, bp, strlen(bp)+1);
return 0;
}