summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openbios/fs/hfs/hfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/openbios/fs/hfs/hfs.c')
-rw-r--r--qemu/roms/openbios/fs/hfs/hfs.c747
1 files changed, 0 insertions, 747 deletions
diff --git a/qemu/roms/openbios/fs/hfs/hfs.c b/qemu/roms/openbios/fs/hfs/hfs.c
deleted file mode 100644
index 0c5fefb47..000000000
--- a/qemu/roms/openbios/fs/hfs/hfs.c
+++ /dev/null
@@ -1,747 +0,0 @@
-/*
- * libhfs - library for reading and writing Macintosh HFS volumes
- * Copyright (C) 1996-1998 Robert Leslie
- *
- * 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 FITNESS 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., 51 Franklin Street - Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * $Id: hfs.c,v 1.15 1998/11/02 22:09:00 rob Exp $
- */
-
-#include "config.h"
-#include "libhfs.h"
-#include "data.h"
-#include "block.h"
-#include "medium.h"
-#include "file.h"
-#include "btree.h"
-#include "node.h"
-#include "record.h"
-#include "volume.h"
-
-const char *hfs_error = "no error"; /* static error string */
-
-hfsvol *hfs_mounts; /* linked list of mounted volumes */
-
-static
-hfsvol *curvol; /* current volume */
-
-
-/*
- * NAME: getvol()
- * DESCRIPTION: validate a volume reference
- */
-static
-int getvol(hfsvol **vol)
-{
- if (*vol == NULL)
- {
- if (curvol == NULL)
- ERROR(EINVAL, "no volume is current");
-
- *vol = curvol;
- }
-
- return 0;
-
-fail:
- return -1;
-}
-
-/* High-Level Volume Routines ============================================== */
-
-/*
- * NAME: hfs->mount()
- * DESCRIPTION: open an HFS volume; return volume descriptor or 0 (error)
- */
-hfsvol *hfs_mount( int os_fd, int pnum)
-{
- hfsvol *vol, *check;
- int mode = HFS_MODE_RDONLY;
-
- /* see if the volume is already mounted */
- for (check = hfs_mounts; check; check = check->next)
- {
- if (check->pnum == pnum && v_same(check, os_fd) == 1)
- {
- vol = check;
- goto done;
- }
- }
-
- vol = ALLOC(hfsvol, 1);
- if (vol == NULL)
- ERROR(ENOMEM, NULL);
-
- v_init(vol, mode);
-
- vol->flags |= HFS_VOL_READONLY;
- if( v_open(vol, os_fd) == -1 )
- goto fail;
-
- /* mount the volume */
-
- if (v_geometry(vol, pnum) == -1 ||
- v_mount(vol) == -1)
- goto fail;
-
- /* add to linked list of volumes */
-
- vol->prev = NULL;
- vol->next = hfs_mounts;
-
- if (hfs_mounts)
- hfs_mounts->prev = vol;
-
- hfs_mounts = vol;
-
-done:
- ++vol->refs;
- curvol = vol;
-
- return vol;
-
-fail:
- if (vol)
- {
- v_close(vol);
- FREE(vol);
- }
-
- return NULL;
-}
-
-
-/*
- * NAME: hfs->umount()
- * DESCRIPTION: close an HFS volume
- */
-int hfs_umount(hfsvol *vol)
-{
- int result = 0;
-
- if (getvol(&vol) == -1)
- goto fail;
-
- if (--vol->refs)
- {
- goto done;
- }
-
- /* close all open files and directories */
-
- while (vol->files)
- {
- if (hfs_close(vol->files) == -1)
- result = -1;
- }
-
- while (vol->dirs)
- {
- if (hfs_closedir(vol->dirs) == -1)
- result = -1;
- }
-
- /* close medium */
-
- if (v_close(vol) == -1)
- result = -1;
-
- /* remove from linked list of volumes */
-
- if (vol->prev)
- vol->prev->next = vol->next;
- if (vol->next)
- vol->next->prev = vol->prev;
-
- if (vol == hfs_mounts)
- hfs_mounts = vol->next;
- if (vol == curvol)
- curvol = NULL;
-
- FREE(vol);
-
-done:
- return result;
-
-fail:
- return -1;
-}
-
-/*
- * NAME: hfs->umountall()
- * DESCRIPTION: unmount all mounted volumes
- */
-void hfs_umountall(void)
-{
- while (hfs_mounts)
- hfs_umount(hfs_mounts);
-}
-
-/*
- * NAME: hfs->getvol()
- * DESCRIPTION: return a pointer to a mounted volume
- */
-hfsvol *hfs_getvol(const char *name)
-{
- hfsvol *vol;
-
- if (name == NULL)
- return curvol;
-
- for (vol = hfs_mounts; vol; vol = vol->next)
- {
- if (d_relstring(name, vol->mdb.drVN) == 0)
- return vol;
- }
-
- return NULL;
-}
-
-/*
- * NAME: hfs->setvol()
- * DESCRIPTION: change the current volume
- */
-void hfs_setvol(hfsvol *vol)
-{
- curvol = vol;
-}
-
-/*
- * NAME: hfs->vstat()
- * DESCRIPTION: return volume statistics
- */
-int hfs_vstat(hfsvol *vol, hfsvolent *ent)
-{
- if (getvol(&vol) == -1)
- goto fail;
-
- strcpy(ent->name, vol->mdb.drVN);
-
- ent->flags = (vol->flags & HFS_VOL_READONLY) ? HFS_ISLOCKED : 0;
-
- ent->totbytes = vol->mdb.drNmAlBlks * vol->mdb.drAlBlkSiz;
- ent->freebytes = vol->mdb.drFreeBks * vol->mdb.drAlBlkSiz;
-
- ent->alblocksz = vol->mdb.drAlBlkSiz;
- ent->clumpsz = vol->mdb.drClpSiz;
-
- ent->numfiles = vol->mdb.drFilCnt;
- ent->numdirs = vol->mdb.drDirCnt;
-
- ent->crdate = d_ltime(vol->mdb.drCrDate);
- ent->mddate = d_ltime(vol->mdb.drLsMod);
- ent->bkdate = d_ltime(vol->mdb.drVolBkUp);
-
- ent->blessed = vol->mdb.drFndrInfo[0];
-
- return 0;
-
-fail:
- return -1;
-}
-
-
-/* High-Level Directory Routines =========================================== */
-
-/*
- * NAME: hfs->chdir()
- * DESCRIPTION: change current HFS directory
- */
-int hfs_chdir(hfsvol *vol, const char *path)
-{
- CatDataRec data;
-
- if (getvol(&vol) == -1 ||
- v_resolve(&vol, path, &data, NULL, NULL, NULL) <= 0)
- goto fail;
-
- if (data.cdrType != cdrDirRec)
- ERROR(ENOTDIR, NULL);
-
- vol->cwd = data.u.dir.dirDirID;
-
- return 0;
-
-fail:
- return -1;
-}
-
-/*
- * NAME: hfs->getcwd()
- * DESCRIPTION: return the current working directory ID
- */
-unsigned long hfs_getcwd(hfsvol *vol)
-{
- if (getvol(&vol) == -1)
- return 0;
-
- return vol->cwd;
-}
-
-/*
- * NAME: hfs->setcwd()
- * DESCRIPTION: set the current working directory ID
- */
-int hfs_setcwd(hfsvol *vol, unsigned long id)
-{
- if (getvol(&vol) == -1)
- goto fail;
-
- if (id == vol->cwd)
- goto done;
-
- /* make sure the directory exists */
-
- if (v_getdthread(vol, id, NULL, NULL) <= 0)
- goto fail;
-
- vol->cwd = id;
-
-done:
- return 0;
-
-fail:
- return -1;
-}
-
-/*
- * NAME: hfs->dirinfo()
- * DESCRIPTION: given a directory ID, return its (name and) parent ID
- */
-int hfs_dirinfo(hfsvol *vol, unsigned long *id, char *name)
-{
- CatDataRec thread;
-
- if (getvol(&vol) == -1 ||
- v_getdthread(vol, *id, &thread, NULL) <= 0)
- goto fail;
-
- *id = thread.u.dthd.thdParID;
-
- if (name)
- strcpy(name, thread.u.dthd.thdCName);
-
- return 0;
-
-fail:
- return -1;
-}
-
-/*
- * NAME: hfs->opendir()
- * DESCRIPTION: prepare to read the contents of a directory
- */
-hfsdir *hfs_opendir(hfsvol *vol, const char *path)
-{
- hfsdir *dir = NULL;
- CatKeyRec key;
- CatDataRec data;
- byte pkey[HFS_CATKEYLEN];
-
- if (getvol(&vol) == -1)
- goto fail;
-
- dir = ALLOC(hfsdir, 1);
- if (dir == NULL)
- ERROR(ENOMEM, NULL);
-
- dir->vol = vol;
-
- if (*path == 0)
- {
- /* meta-directory containing root dirs from all mounted volumes */
-
- dir->dirid = 0;
- dir->vptr = hfs_mounts;
- }
- else
- {
- if (v_resolve(&vol, path, &data, NULL, NULL, NULL) <= 0)
- goto fail;
-
- if (data.cdrType != cdrDirRec)
- ERROR(ENOTDIR, NULL);
-
- dir->dirid = data.u.dir.dirDirID;
- dir->vptr = NULL;
-
- r_makecatkey(&key, dir->dirid, "");
- r_packcatkey(&key, pkey, NULL);
-
- if (bt_search(&vol->cat, pkey, &dir->n) <= 0)
- goto fail;
- }
-
- dir->prev = NULL;
- dir->next = vol->dirs;
-
- if (vol->dirs)
- vol->dirs->prev = dir;
-
- vol->dirs = dir;
-
- return dir;
-
-fail:
- FREE(dir);
- return NULL;
-}
-
-/*
- * NAME: hfs->readdir()
- * DESCRIPTION: return the next entry in the directory
- */
-int hfs_readdir(hfsdir *dir, hfsdirent *ent)
-{
- CatKeyRec key;
- CatDataRec data;
- const byte *ptr;
-
- if (dir->dirid == 0)
- {
- hfsvol *vol;
- char cname[HFS_MAX_FLEN + 1];
-
- for (vol = hfs_mounts; vol; vol = vol->next)
- {
- if (vol == dir->vptr)
- break;
- }
-
- if (vol == NULL)
- ERROR(ENOENT, "no more entries");
-
- if (v_getdthread(vol, HFS_CNID_ROOTDIR, &data, NULL) <= 0 ||
- v_catsearch(vol, HFS_CNID_ROOTPAR, data.u.dthd.thdCName,
- &data, cname, NULL) <= 0)
- goto fail;
-
- r_unpackdirent(HFS_CNID_ROOTPAR, cname, &data, ent);
-
- dir->vptr = vol->next;
-
- goto done;
- }
-
- if (dir->n.rnum == -1)
- ERROR(ENOENT, "no more entries");
-
- while (1)
- {
- ++dir->n.rnum;
-
- while (dir->n.rnum >= dir->n.nd.ndNRecs)
- {
- if (dir->n.nd.ndFLink == 0)
- {
- dir->n.rnum = -1;
- ERROR(ENOENT, "no more entries");
- }
-
- if (bt_getnode(&dir->n, dir->n.bt, dir->n.nd.ndFLink) == -1)
- {
- dir->n.rnum = -1;
- goto fail;
- }
-
- dir->n.rnum = 0;
- }
-
- ptr = HFS_NODEREC(dir->n, dir->n.rnum);
-
- r_unpackcatkey(ptr, &key);
-
- if (key.ckrParID != dir->dirid)
- {
- dir->n.rnum = -1;
- ERROR(ENOENT, "no more entries");
- }
-
- r_unpackcatdata(HFS_RECDATA(ptr), &data);
-
- switch (data.cdrType)
- {
- case cdrDirRec:
- case cdrFilRec:
- r_unpackdirent(key.ckrParID, key.ckrCName, &data, ent);
- goto done;
-
- case cdrThdRec:
- case cdrFThdRec:
- break;
-
- default:
- dir->n.rnum = -1;
- ERROR(EIO, "unexpected directory entry found");
- }
- }
-
-done:
- return 0;
-
-fail:
- return -1;
-}
-
-/*
- * NAME: hfs->closedir()
- * DESCRIPTION: stop reading a directory
- */
-int hfs_closedir(hfsdir *dir)
-{
- hfsvol *vol = dir->vol;
-
- if (dir->prev)
- dir->prev->next = dir->next;
- if (dir->next)
- dir->next->prev = dir->prev;
- if (dir == vol->dirs)
- vol->dirs = dir->next;
-
- FREE(dir);
-
- return 0;
-}
-
-/* High-Level File Routines ================================================ */
-
-/*
- * NAME: hfs->open()
- * DESCRIPTION: prepare a file for I/O
- */
-hfsfile *hfs_open(hfsvol *vol, const char *path)
-{
- hfsfile *file = NULL;
-
- if (getvol(&vol) == -1)
- goto fail;
-
- file = ALLOC(hfsfile, 1);
- if (file == NULL)
- ERROR(ENOMEM, NULL);
-
- if (v_resolve(&vol, path, &file->cat, &file->parid, file->name, NULL) <= 0)
- goto fail;
-
- if (file->cat.cdrType != cdrFilRec)
- ERROR(EISDIR, NULL);
-
- /* package file handle for user */
-
- file->vol = vol;
- file->flags = 0;
-
- f_selectfork(file, fkData);
-
- file->prev = NULL;
- file->next = vol->files;
-
- if (vol->files)
- vol->files->prev = file;
-
- vol->files = file;
-
- return file;
-
-fail:
- FREE(file);
- return NULL;
-}
-
-/*
- * NAME: hfs->setfork()
- * DESCRIPTION: select file fork for I/O operations
- */
-int hfs_setfork(hfsfile *file, int fork)
-{
- int result = 0;
-
- f_selectfork(file, fork ? fkRsrc : fkData);
-
- return result;
-}
-
-/*
- * NAME: hfs->getfork()
- * DESCRIPTION: return the current fork for I/O operations
- */
-int hfs_getfork(hfsfile *file)
-{
- return file->fork != fkData;
-}
-
-/*
- * NAME: hfs->read()
- * DESCRIPTION: read from an open file
- */
-unsigned long hfs_read(hfsfile *file, void *buf, unsigned long len)
-{
- unsigned long *lglen, count;
- byte *ptr = buf;
-
- f_getptrs(file, NULL, &lglen, NULL);
-
- if (file->pos + len > *lglen)
- len = *lglen - file->pos;
-
- count = len;
- while (count)
- {
- unsigned long bnum, offs, chunk;
-
- bnum = file->pos >> HFS_BLOCKSZ_BITS;
- offs = file->pos & (HFS_BLOCKSZ - 1);
-
- chunk = HFS_BLOCKSZ - offs;
- if (chunk > count)
- chunk = count;
-
- if (offs == 0 && chunk == HFS_BLOCKSZ)
- {
- if (f_getblock(file, bnum, (block *) ptr) == -1)
- goto fail;
- }
- else
- {
- block b;
-
- if (f_getblock(file, bnum, &b) == -1)
- goto fail;
-
- memcpy(ptr, b + offs, chunk);
- }
-
- ptr += chunk;
-
- file->pos += chunk;
- count -= chunk;
- }
-
- return len;
-
-fail:
- return -1;
-}
-
-/*
- * NAME: hfs->seek()
- * DESCRIPTION: change file seek pointer
- */
-unsigned long hfs_seek(hfsfile *file, long offset, int from)
-{
- unsigned long *lglen, newpos;
-
- f_getptrs(file, NULL, &lglen, NULL);
-
- switch (from)
- {
- case HFS_SEEK_SET:
- newpos = (offset < 0) ? 0 : offset;
- break;
-
- case HFS_SEEK_CUR:
- if (offset < 0 && (unsigned long) -offset > file->pos)
- newpos = 0;
- else
- newpos = file->pos + offset;
- break;
-
- case HFS_SEEK_END:
- if (offset < 0 && (unsigned long) -offset > *lglen)
- newpos = 0;
- else
- newpos = *lglen + offset;
- break;
-
- default:
- ERROR(EINVAL, NULL);
- }
-
- if (newpos > *lglen)
- newpos = *lglen;
-
- file->pos = newpos;
-
- return newpos;
-
-fail:
- return -1;
-}
-
-/*
- * NAME: hfs->close()
- * DESCRIPTION: close a file
- */
-int hfs_close(hfsfile *file)
-{
- hfsvol *vol = file->vol;
- int result = 0;
-
- if (file->prev)
- file->prev->next = file->next;
- if (file->next)
- file->next->prev = file->prev;
- if (file == vol->files)
- vol->files = file->next;
-
- FREE(file);
-
- return result;
-}
-
-/* High-Level Catalog Routines ============================================= */
-
-/*
- * NAME: hfs->stat()
- * DESCRIPTION: return catalog information for an arbitrary path
- */
-int hfs_stat(hfsvol *vol, const char *path, hfsdirent *ent)
-{
- CatDataRec data;
- unsigned long parid;
- char name[HFS_MAX_FLEN + 1];
-
- if (getvol(&vol) == -1 ||
- v_resolve(&vol, path, &data, &parid, name, NULL) <= 0)
- goto fail;
-
- r_unpackdirent(parid, name, &data, ent);
-
- return 0;
-
-fail:
- return -1;
-}
-
-/*
- * NAME: hfs->fstat()
- * DESCRIPTION: return catalog information for an open file
- */
-int hfs_fstat(hfsfile *file, hfsdirent *ent)
-{
- r_unpackdirent(file->parid, file->name, &file->cat, ent);
-
- return 0;
-}
-
-/*
- * NAME: hfs->probe()
- * DESCRIPTION: return whether a HFS filesystem is present at the given offset
- */
-int hfs_probe(int fd, long long offset)
-{
- return v_probe(fd, offset);
-}