all routines

This commit is contained in:
Elliot Nunn 2018-09-19 23:33:49 +08:00
parent e46b7c4215
commit c5f0131c44
2 changed files with 451 additions and 334 deletions

604
README
View File

@ -10,23 +10,23 @@ Exported Data
const char *hfs_error;
This contains a pointer to a C string describing the last HFS error.
It is generally only valid after an HFS routine has returned an error
code (-1 or a NULL pointer).
This contains a pointer to a C string describing the last HFS error.
It is generally only valid after an HFS routine has returned an error
code (-1 or a NULL pointer).
This string is encoded using ISO 8859-1.
This string is encoded using ISO 8859-1.
In all cases when an error occurs, the global variable `errno' is also
set to an appropriate value.
In all cases when an error occurs, the global variable `errno' is also
set to an appropriate value.
unsigned char hfs_charorder[];
This array contains the relative sorting order of characters in HFS
filenames according to the semantics of the Macintosh character set
and the MacOS string comparison routines as used by HFS. The array can
be indexed by unsigned character quantities; the resulting value can be
compared to other array values to determine the relative sorting order
of the corresponding character indices.
This array contains the relative sorting order of characters in HFS
filenames according to the semantics of the Macintosh character set
and the MacOS string comparison routines as used by HFS. The array can
be indexed by unsigned character quantities; the resulting value can be
compared to other array values to determine the relative sorting order
of the corresponding character indices.
Public Routines
@ -34,484 +34,484 @@ Public Routines
hfsvol *hfs_mount(const char *path, int pnum, int flags);
This routine attempts to open an HFS volume from a source pathname. The
given `pnum' indicates which ordinal HFS partition is to be mounted,
or can be 0 to indicate the entire medium should be mounted (ignoring
any partition structure). If this value is not 0, the requested
partition must exist.
This routine attempts to open an HFS volume from a source pathname. The
given `pnum' indicates which ordinal HFS partition is to be mounted,
or can be 0 to indicate the entire medium should be mounted (ignoring
any partition structure). If this value is not 0, the requested
partition must exist.
The `flags' argument specifies how the volume should be mounted.
HFS_MODE_RDONLY means the volume should be mounted read-only.
HFS_MODE_RDWR means the volume must be opened read/write. HFS_MODE_ANY
means the volume can be mounted either read-only or read/write, with
preference for the latter.
The `flags' argument specifies how the volume should be mounted.
HFS_MODE_RDONLY means the volume should be mounted read-only.
HFS_MODE_RDWR means the volume must be opened read/write. HFS_MODE_ANY
means the volume can be mounted either read-only or read/write, with
preference for the latter.
The `flags' argument may also specify volume options. HFS_OPT_NOCACHE
means not to perform any internal block caching, such as would be
unnecessary for a volume residing in RAM, or if the associated overhead
is not desired. HFS_OPT_ZERO means that newly-allocated blocks should be
zero-initialized before use, primarily as a security feature for systems
on which blocks may otherwise contain random data. Neither of these
options should normally be necessary, and both may affect performance.
The `flags' argument may also specify volume options. HFS_OPT_NOCACHE
means not to perform any internal block caching, such as would be
unnecessary for a volume residing in RAM, or if the associated overhead
is not desired. HFS_OPT_ZERO means that newly-allocated blocks should be
zero-initialized before use, primarily as a security feature for systems
on which blocks may otherwise contain random data. Neither of these
options should normally be necessary, and both may affect performance.
If an error occurs, this function returns NULL. Otherwise a pointer to a
volume structure is returned. This pointer is used to access the volume
and must eventually be passed to hfs_umount() to flush and close the
volume and free all associated memory.
If an error occurs, this function returns NULL. Otherwise a pointer to a
volume structure is returned. This pointer is used to access the volume
and must eventually be passed to hfs_umount() to flush and close the
volume and free all associated memory.
int hfs_flush(hfsvol *vol);
This routine causes all pending changes to be flushed to an HFS volume.
If a volume is kept open for a long period of time, it would be wise
to call this periodically to avoid corrupting the volume due to
unforeseen circumstances (power failure, floppy eject, etc.)
This routine causes all pending changes to be flushed to an HFS volume.
If a volume is kept open for a long period of time, it would be wise
to call this periodically to avoid corrupting the volume due to
unforeseen circumstances (power failure, floppy eject, etc.)
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
void hfs_flushall(void);
This routine is similar to hfs_flush() except that all mounted volumes
are flushed, and errors are not reported.
This routine is similar to hfs_flush() except that all mounted volumes
are flushed, and errors are not reported.
int hfs_umount(hfsvol *vol);
The specified HFS volume is unmounted; all open files and directories
on the volume are closed, all pending changes to the volume are
flushed, and all memory allocated for the volume is freed.
The specified HFS volume is unmounted; all open files and directories
on the volume are closed, all pending changes to the volume are
flushed, and all memory allocated for the volume is freed.
All volumes opened with hfs_mount() must eventually be closed with
hfs_umount(), or they will risk corruption.
All volumes opened with hfs_mount() must eventually be closed with
hfs_umount(), or they will risk corruption.
If an error occurs, this function returns -1. Otherwise it returns 0.
In either case, the volume structure pointer will become invalid, as
will all pointers to open file or directory structures associated with
the volume.
If an error occurs, this function returns -1. Otherwise it returns 0.
In either case, the volume structure pointer will become invalid, as
will all pointers to open file or directory structures associated with
the volume.
void hfs_umountall(void);
This routine is similar to hfs_umount() except that all mounted volumes
are closed, and errors are not reported.
This routine is similar to hfs_umount() except that all mounted volumes
are closed, and errors are not reported.
This routine may be useful to call just before a process terminates to
make sure any remaining open volumes are properly closed.
This routine may be useful to call just before a process terminates to
make sure any remaining open volumes are properly closed.
hfsvol *hfs_getvol(const char *name);
This routines searches all mounted volumes for one having the given
`name', and returns its volume structure pointer. If more than one
volume have the same name, the most recently mounted one is returned. If
no volume matches the given name, a NULL pointer is returned.
This routines searches all mounted volumes for one having the given
`name', and returns its volume structure pointer. If more than one
volume have the same name, the most recently mounted one is returned. If
no volume matches the given name, a NULL pointer is returned.
The given `name' is assumed to be encoded using MacOS Standard Roman.
The given `name' is assumed to be encoded using MacOS Standard Roman.
If a NULL pointer is passed to this routine, the current volume is
returned, if any.
If a NULL pointer is passed to this routine, the current volume is
returned, if any.
void hfs_setvol(hfsvol *vol);
The routine changes the "current" volume. Most HFS routines will accept
a NULL volume pointer to mean the current volume; by default, the
current volume is the last one which was mounted.
The routine changes the "current" volume. Most HFS routines will accept
a NULL volume pointer to mean the current volume; by default, the
current volume is the last one which was mounted.
int hfs_vstat(hfsvol *vol, hfsvolent *ent);
This routine fills the volume entity structure `*ent' with information
about a mounted volume. The fields of the structure are defined in
the hfs.h header file.
This routine fills the volume entity structure `*ent' with information
about a mounted volume. The fields of the structure are defined in
the hfs.h header file.
This routine returns 0 unless a NULL pointer is passed for the volume
and no volume is current, in which case it returns -1.
This routine returns 0 unless a NULL pointer is passed for the volume
and no volume is current, in which case it returns -1.
int hfs_vsetattr(hfsvol *vol, hfsvolent *ent);
This routine allows some attributes of a volume to be changed. The
attributes which may be changed are: ent->clumpsz, ent->crdate,
ent->mddate, ent->bkdate, and ent->blessed. Note that the default file
clump size may only be changed to be a multiple of the volume's
allocation block size, and the "blessed" folder must either be 0 or a
valid folder CNID.
This routine allows some attributes of a volume to be changed. The
attributes which may be changed are: ent->clumpsz, ent->crdate,
ent->mddate, ent->bkdate, and ent->blessed. Note that the default file
clump size may only be changed to be a multiple of the volume's
allocation block size, and the "blessed" folder must either be 0 or a
valid folder CNID.
To change the volume's name, use hfs_rename().
To change the volume's name, use hfs_rename().
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
----- Directory Routines -----
int hfs_chdir(hfsvol *vol, const char *path);
The "current working directory" for the given volume is changed.
`path' can be either a relative or absolute HFS path.
The "current working directory" for the given volume is changed.
`path' can be either a relative or absolute HFS path.
The given `path' is assumed to be encoded using MacOS Standard Roman.
The given `path' is assumed to be encoded using MacOS Standard Roman.
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
long hfs_getcwd(hfsvol *vol);
The internal directory ID of the current working directory for the
given volume is returned. This value is typically only useful for
passing to hfs_setcwd() or hfs_dirinfo().
The internal directory ID of the current working directory for the
given volume is returned. This value is typically only useful for
passing to hfs_setcwd() or hfs_dirinfo().
int hfs_setcwd(hfsvol *vol, long id);
This routine changes the current working directory for the given
volume. A directory must exist with the given id.
This routine changes the current working directory for the given
volume. A directory must exist with the given id.
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
int hfs_dirinfo(hfsvol *vol, long *id, char *name);
This function looks up the given directory ID `*id' and stores in its
place the directory ID of its parent. If `name' is not NULL, the name
of the (child) directory is also stored in the buffer pointed to by it,
which must be at least HFS_MAX_FLEN + 1 (32) bytes long.
This function looks up the given directory ID `*id' and stores in its
place the directory ID of its parent. If `name' is not NULL, the name
of the (child) directory is also stored in the buffer pointed to by it,
which must be at least HFS_MAX_FLEN + 1 (32) bytes long.
The string `name' will be encoded using MacOS Standard Roman.
The string `name' will be encoded using MacOS Standard Roman.
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
This function can be called repeatedly to construct a full pathname
to the current working directory. The root directory of a volume
always has a directory ID of HFS_CNID_ROOTDIR, and a pseudo-parent ID
of HFS_CNID_ROOTPAR.
This function can be called repeatedly to construct a full pathname
to the current working directory. The root directory of a volume
always has a directory ID of HFS_CNID_ROOTDIR, and a pseudo-parent ID
of HFS_CNID_ROOTPAR.
hfsdir *hfs_opendir(hfsvol *vol, const char *path);
This function prepares to read the contents of a directory. `path'
must be either an absolute or relative pathname to the desired HFS
directory. As a special case, if `path' is an empty string, a
"meta-directory" will be opened containing the root directories from
all of the currently mounted volumes.
This function prepares to read the contents of a directory. `path'
must be either an absolute or relative pathname to the desired HFS
directory. As a special case, if `path' is an empty string, a
"meta-directory" will be opened containing the root directories from
all of the currently mounted volumes.
The string `path' is assumed to be encoded using MacOS Standard Roman.
The string `path' is assumed to be encoded using MacOS Standard Roman.
This function returns a pointer which must be passed to the other
directory-related routines to read the directory.
This function returns a pointer which must be passed to the other
directory-related routines to read the directory.
If an error occurs, this function returns a NULL pointer.
If an error occurs, this function returns a NULL pointer.
int hfs_readdir(hfsdir *dir, hfsdirent *ent);
This routine fills the directory entity structure `*ent' with
information about the next item in the given open directory. The
fields of the structure are defined in the hfs.h header file.
This routine fills the directory entity structure `*ent' with
information about the next item in the given open directory. The
fields of the structure are defined in the hfs.h header file.
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
When no more items occur in the directory, this function returns -1
and sets `errno' to ENOENT.
When no more items occur in the directory, this function returns -1
and sets `errno' to ENOENT.
int hfs_closedir(hfsdir *dir);
This function closes an open directory and frees all associated
memory.
This function closes an open directory and frees all associated
memory.
If an error occurs, this function returns -1. Otherwise it returns 0.
In either case, the directory structure pointer will no longer be valid.
If an error occurs, this function returns -1. Otherwise it returns 0.
In either case, the directory structure pointer will no longer be valid.
----- File Routines -----
hfsfile *hfs_create(hfsvol *vol, const char *path,
const char *type, const char *creator);
const char *type, const char *creator);
This routine creates a new, empty file with the given path, type, and
creator. The type and creator must be strings of length 4, and have
particular meaning under MacOS.
This routine creates a new, empty file with the given path, type, and
creator. The type and creator must be strings of length 4, and have
particular meaning under MacOS.
The given `path' is assumed to be encoded using MacOS Standard Roman.
The given `path' is assumed to be encoded using MacOS Standard Roman.
If the creation is successful, the file is opened and a pointer to a
file structure is returned, the same as if hfs_open() had been called.
If the creation is successful, the file is opened and a pointer to a
file structure is returned, the same as if hfs_open() had been called.
If an error occurs, this function returns a NULL pointer.
If an error occurs, this function returns a NULL pointer.
hfsfile *hfs_open(hfsvol *vol, const char *path);
This function opens an HFS file in preparation for I/O. Both forks of
the file may be manipulated once the file is opened; hfs_setfork() is
used to select the current fork. By default, the data fork is current.
This function opens an HFS file in preparation for I/O. Both forks of
the file may be manipulated once the file is opened; hfs_setfork() is
used to select the current fork. By default, the data fork is current.
The given `path' is assumed to be encoded using MacOS Standard Roman.
The given `path' is assumed to be encoded using MacOS Standard Roman.
A pointer to a file structure is returned. This pointer should be
passed to other routines to manipulate the file.
A pointer to a file structure is returned. This pointer should be
passed to other routines to manipulate the file.
If an error occurs, this function returns a NULL pointer.
If an error occurs, this function returns a NULL pointer.
int hfs_setfork(hfsfile *file, int fork);
This routine selects the current fork in an open file for I/O. HFS
files have two forks, data and resource. Resource forks normally contain
structured data, although these HFS routines make no distinction
between forks when reading or writing. It is up to higher-level
applications to make sense of the information read or written from
either fork.
This routine selects the current fork in an open file for I/O. HFS
files have two forks, data and resource. Resource forks normally contain
structured data, although these HFS routines make no distinction
between forks when reading or writing. It is up to higher-level
applications to make sense of the information read or written from
either fork.
If 0 is passed to this routine, the data fork is selected. Otherwise
the resource fork is selected. The seek pointer for the file is
automatically reset to the beginning of the newly selected fork.
If 0 is passed to this routine, the data fork is selected. Otherwise
the resource fork is selected. The seek pointer for the file is
automatically reset to the beginning of the newly selected fork.
As a side effect, this routine causes any excess disk blocks allocated
for the fork which was current before the call to be freed; normally
extra blocks are allocated during file writes to promote contiguity.
This routine will return -1 if an error occurs in this process;
otherwise it will return 0. The current fork will have been changed
regardless.
As a side effect, this routine causes any excess disk blocks allocated
for the fork which was current before the call to be freed; normally
extra blocks are allocated during file writes to promote contiguity.
This routine will return -1 if an error occurs in this process;
otherwise it will return 0. The current fork will have been changed
regardless.
int hfs_getfork(hfsfile *file);
This routine returns an indication of which fork is currently active
for I/O operations on the given file. If 0 is returned, the data fork
is selected. Otherwise the resource fork is selected.
This routine returns an indication of which fork is currently active
for I/O operations on the given file. If 0 is returned, the data fork
is selected. Otherwise the resource fork is selected.
long hfs_read(hfsfile *file, void *ptr, unsigned long len);
This routine reads up to `len' bytes from the current fork of an HFS
file and places them into the buffer pointed to by `ptr' (which must be
at least `len' bytes long.) The number of bytes actually read is
returned, and may be less than `len' if the end of the file is reached.
This routine reads up to `len' bytes from the current fork of an HFS
file and places them into the buffer pointed to by `ptr' (which must be
at least `len' bytes long.) The number of bytes actually read is
returned, and may be less than `len' if the end of the file is reached.
If this routine returns 0, there is no more data to be read from the
file. If an error occurs, this routine will return -1.
If this routine returns 0, there is no more data to be read from the
file. If an error occurs, this routine will return -1.
It is most efficient to read data in multiples of HFS_BLOCKSZ byte
blocks at a time.
It is most efficient to read data in multiples of HFS_BLOCKSZ byte
blocks at a time.
long hfs_write(hfsfile *file, const void *ptr, unsigned long len);
This routine writes up to `len' bytes of data to the current fork of an
HFS file from the buffer pointed to by `ptr'. The number of bytes
actually written is returned. If an error occurs, this routine will
return -1.
This routine writes up to `len' bytes of data to the current fork of an
HFS file from the buffer pointed to by `ptr'. The number of bytes
actually written is returned. If an error occurs, this routine will
return -1.
If the end of the file is reached before all bytes have been written,
the file is automatically extended.
If the end of the file is reached before all bytes have been written,
the file is automatically extended.
It is most efficient to write data in multiples of HFS_BLOCKSZ byte
blocks at a time.
It is most efficient to write data in multiples of HFS_BLOCKSZ byte
blocks at a time.
int hfs_truncate(hfsfile *file, unsigned long len);
This routine causes the current fork of the specified open file to be
truncated to at most `len' bytes.
This routine causes the current fork of the specified open file to be
truncated to at most `len' bytes.
The disk blocks associated with the freed portion of the file are not
actually deallocated until either the current fork is changed or the
file is closed.
The disk blocks associated with the freed portion of the file are not
actually deallocated until either the current fork is changed or the
file is closed.
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
long hfs_seek(hfsfile *file, long offset, int from);
This routine changes the current seek pointer for the specified open
file. This pointer determines where the next call to hfs_read() or
hfs_write() will read or write data within the current fork.
This routine changes the current seek pointer for the specified open
file. This pointer determines where the next call to hfs_read() or
hfs_write() will read or write data within the current fork.
If `from' is HFS_SEEK_SET, the pointer is set to the absolute position
given by `offset'.
If `from' is HFS_SEEK_SET, the pointer is set to the absolute position
given by `offset'.
If `from' is HFS_SEEK_CUR, the pointer is offset from its current
position by the amount `offset'. Positive offsets seek forward; negative
offsets seek backward.
If `from' is HFS_SEEK_CUR, the pointer is offset from its current
position by the amount `offset'. Positive offsets seek forward; negative
offsets seek backward.
If `from' is HFS_SEEK_END, the pointer is offset from the end of the
file by the amount `offset', which ought not be positive.
If `from' is HFS_SEEK_END, the pointer is offset from the end of the
file by the amount `offset', which ought not be positive.
It is not presently possible to set the seek pointer beyond the logical
end of the file.
It is not presently possible to set the seek pointer beyond the logical
end of the file.
The new absolute position of the seek pointer is returned, unless an
invalid argument was specified, in which case -1 is returned.
The new absolute position of the seek pointer is returned, unless an
invalid argument was specified, in which case -1 is returned.
int hfs_close(hfsfile *file);
This routine causes all pending changes to the specified file to be
flushed, and all storage associated with the file structure to be
freed. Any excess disk blocks associated with the file are also
deallocated at this time.
This routine causes all pending changes to the specified file to be
flushed, and all storage associated with the file structure to be
freed. Any excess disk blocks associated with the file are also
deallocated at this time.
If an error occurs, this routine returns -1. Otherwise it returns 0.
In either case, the file structure pointer will no longer be valid.
If an error occurs, this routine returns -1. Otherwise it returns 0.
In either case, the file structure pointer will no longer be valid.
----- Catalog Routines -----
int hfs_stat(hfsvol *vol, const char *path, hfsdirent *ent);
This routine fills the directory entity structure `*ent' with
information about the file or directory specified by `path' on the
given volume. The fields of the structure are defined in the hfs.h
header file.
This routine fills the directory entity structure `*ent' with
information about the file or directory specified by `path' on the
given volume. The fields of the structure are defined in the hfs.h
header file.
The given `path' is assumed to be encoded using MacOS Standard Roman.
The given `path' is assumed to be encoded using MacOS Standard Roman.
If there is no such path, or if another error occurs, this routine
returns -1. Otherwise it returns 0.
If there is no such path, or if another error occurs, this routine
returns -1. Otherwise it returns 0.
int hfs_fstat(hfsfile *file, hfsdirent *ent);
This routine is similar to hfs_stat() except it returns information
about a file that is already open.
This routine is similar to hfs_stat() except it returns information
about a file that is already open.
If an error occurs, this routine returns -1. Otherwise it returns 0.
If an error occurs, this routine returns -1. Otherwise it returns 0.
int hfs_setattr(hfsvol *vol, const char *path, const hfsdirent *ent);
This routine changes various attributes of an existing file or
directory. The attributes which may be changed are: ent->crdate,
ent->mddate, ent->bkdate, ent->fdflags, ent->fdlocation,
ent->u.file.type, ent->u.file.creator, and ent->u.dir.rect. Also, the
locked status of a file may be changed with ent->flags & HFS_ISLOCKED.
This routine changes various attributes of an existing file or
directory. The attributes which may be changed are: ent->crdate,
ent->mddate, ent->bkdate, ent->fdflags, ent->fdlocation,
ent->u.file.type, ent->u.file.creator, and ent->u.dir.rect. Also, the
locked status of a file may be changed with ent->flags & HFS_ISLOCKED.
The given `path' is assumed to be encoded using MacOS Standard Roman.
The given `path' is assumed to be encoded using MacOS Standard Roman.
If an error occurs, this routine returns -1. Otherwise it returns 0.
If an error occurs, this routine returns -1. Otherwise it returns 0.
int hfs_fsetattr(hfsfile *file, const hfsdirent *ent);
This routine is similar to hfs_setattr() except it manipulates a file
that is already open.
This routine is similar to hfs_setattr() except it manipulates a file
that is already open.
If an error occurs, this routine returns -1. Otherwise it returns 0.
If an error occurs, this routine returns -1. Otherwise it returns 0.
int hfs_mkdir(hfsvol *vol, const char *path);
This routine creates a new, empty directory with the given path.
All parent directories must already exist, but there must not already
be a file or directory with the complete given path.
This routine creates a new, empty directory with the given path.
All parent directories must already exist, but there must not already
be a file or directory with the complete given path.
The given `path' is assumed to be encoded using MacOS Standard Roman.
The given `path' is assumed to be encoded using MacOS Standard Roman.
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
int hfs_rmdir(hfsvol *vol, const char *path);
This routine deletes the directory with the given path. The directory
must be empty.
This routine deletes the directory with the given path. The directory
must be empty.
The given `path' is assumed to be encoded using MacOS Standard Roman.
The given `path' is assumed to be encoded using MacOS Standard Roman.
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
int hfs_delete(hfsvol *vol, const char *path);
This routine deletes both forks of the file with the given path.
This routine deletes both forks of the file with the given path.
The given `path' is assumed to be encoded using MacOS Standard Roman.
The given `path' is assumed to be encoded using MacOS Standard Roman.
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
int hfs_rename(hfsvol *vol, const char *srcpath, const char *dstpath);
This routine moves and/or renames the given `srcpath' to `dstpath'.
The source must exist; the destination must not exist, unless it is a
directory, in which case an attempt will be made to move the source
into the destination directory without changing its name.
This routine moves and/or renames the given `srcpath' to `dstpath'.
The source must exist; the destination must not exist, unless it is a
directory, in which case an attempt will be made to move the source
into the destination directory without changing its name.
If both `srcpath' and `dstpath' refer to root directories, the volume
specified by `srcpath' will be renamed. Note that volume names may
only have 1-27 (HFS_MAX_VLEN) characters, while all other names may
have 1-31 (HFS_MAX_FLEN) characters.
If both `srcpath' and `dstpath' refer to root directories, the volume
specified by `srcpath' will be renamed. Note that volume names may
only have 1-27 (HFS_MAX_VLEN) characters, while all other names may
have 1-31 (HFS_MAX_FLEN) characters.
The given `srcpath' and `dstpath' are assumed to be encoded using MacOS
Standard Roman.
The given `srcpath' and `dstpath' are assumed to be encoded using MacOS
Standard Roman.
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
----- Media Routines -----
int hfs_zero(const char *path, unsigned int maxparts,
unsigned long *blocks);
unsigned long *blocks);
This routine initializes a medium with a new, empty driver descriptor
record and partition map. This is only necessary if it is desired to
partition the medium; the medium can be used as a whole without
partitions by specifying 0 to the routines which require a partition
number.
This routine initializes a medium with a new, empty driver descriptor
record and partition map. This is only necessary if it is desired to
partition the medium; the medium can be used as a whole without
partitions by specifying 0 to the routines which require a partition
number.
The partition map will be empty, with the exception of an entry for the
partition map itself, plus an entry for the rest of the medium as free
space. To be useful, one or more HFS partitions should be created with
hfs_mkpart().
The partition map will be empty, with the exception of an entry for the
partition map itself, plus an entry for the rest of the medium as free
space. To be useful, one or more HFS partitions should be created with
hfs_mkpart().
The partition map will be created just large enough to allow `maxparts'
individual partitions to be created, not counting the partitions created
automatically by this routine. This number should be conservative, as
it may be impossible to create more than this many partitions for the
lifetime of the medium without re-initializing.
The partition map will be created just large enough to allow `maxparts'
individual partitions to be created, not counting the partitions created
automatically by this routine. This number should be conservative, as
it may be impossible to create more than this many partitions for the
lifetime of the medium without re-initializing.
If `blocks' is not NULL, the total number of blocks available for
partitioning (after the partition map structures have been created) will
be stored at this location.
If `blocks' is not NULL, the total number of blocks available for
partitioning (after the partition map structures have been created) will
be stored at this location.
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
int hfs_mkpart(const char *path, unsigned long len);
This routine creates a new HFS partition having `len' blocks on the
given medium. Space for the partition will be taken from the available
free space as indicated in the existing partition map.
This routine creates a new HFS partition having `len' blocks on the
given medium. Space for the partition will be taken from the available
free space as indicated in the existing partition map.
It may not be possible to create the requested partition if there are
not enough free contiguous blocks on the medium, or if there is only
one slot left in the partition map and the request does not specify
all the remaining blocks in the free space. (The partition map cannot
leave any blocks in the medium unaccounted for.)
It may not be possible to create the requested partition if there are
not enough free contiguous blocks on the medium, or if there is only
one slot left in the partition map and the request does not specify
all the remaining blocks in the free space. (The partition map cannot
leave any blocks in the medium unaccounted for.)
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
int hfs_nparts(const char *path);
This routine determines the number of HFS partitions present on the
given medium, if any. If the medium specified by `path' is not
partitioned, -1 will be returned. Otherwise, a number denoting the total
number of HFS partitions is returned, including (possibly) 0.
This routine determines the number of HFS partitions present on the
given medium, if any. If the medium specified by `path' is not
partitioned, -1 will be returned. Otherwise, a number denoting the total
number of HFS partitions is returned, including (possibly) 0.
The number returned by this routine can help determine if a particular
medium is partitioned, and if so, the allowable range of partition
numbers which can be passed to the routines which require one. However,
passing 0 as a partition number always refers to the entire medium,
ignoring all partitions.
The number returned by this routine can help determine if a particular
medium is partitioned, and if so, the allowable range of partition
numbers which can be passed to the routines which require one. However,
passing 0 as a partition number always refers to the entire medium,
ignoring all partitions.
If an error occurs, this function returns -1.
If an error occurs, this function returns -1.
int hfs_format(const char *path, int pnum, int mode, const char *vname,
int nbadblocks, const unsigned long badblocks[]);
int nbadblocks, const unsigned long badblocks[]);
This routine writes a new HFS file system to the specified `path', which
should be a block device or a writable file. The size of the volume is
determined either by the maximum size of the device or size of the file,
or by the size of the indicated partition within the medium.
This routine writes a new HFS file system to the specified `path', which
should be a block device or a writable file. The size of the volume is
determined either by the maximum size of the device or size of the file,
or by the size of the indicated partition within the medium.
If `pnum' is > 0, it selects an ordinal HFS partition in the device
to receive the file system. The partition must already exist; an error
will result if it cannot be found. With `pnum' == 0, any partition
structure on the existing medium will be ignored, and the entire
device will be used for the new HFS volume.
If `pnum' is > 0, it selects an ordinal HFS partition in the device
to receive the file system. The partition must already exist; an error
will result if it cannot be found. With `pnum' == 0, any partition
structure on the existing medium will be ignored, and the entire
device will be used for the new HFS volume.
Volume options may be specified in the `mode' argument. In addition to
the options accepted by hfs_mount(), HFS_OPT_2048 may be specified to
request that the volume allocation blocks be aligned on physical
2048-byte block boundaries. Such a constraint is necessary to support
some hybrid CD-ROM file system formats, but is otherwise unnecessary and
may result in fewer allocation blocks altogether.
Volume options may be specified in the `mode' argument. In addition to
the options accepted by hfs_mount(), HFS_OPT_2048 may be specified to
request that the volume allocation blocks be aligned on physical
2048-byte block boundaries. Such a constraint is necessary to support
some hybrid CD-ROM file system formats, but is otherwise unnecessary and
may result in fewer allocation blocks altogether.
The volume is given the name `vname', which must be between 1 and
HFS_MAX_VLEN (27) characters in length inclusively, and cannot contain
any colons (':'). This string is assumed to be encoded using MacOS
Standard Roman.
The volume is given the name `vname', which must be between 1 and
HFS_MAX_VLEN (27) characters in length inclusively, and cannot contain
any colons (':'). This string is assumed to be encoded using MacOS
Standard Roman.
It is possible to map out or "spare" bad blocks on the device such that
the file system will be made aware of these blocks and will not attempt
to use them to store data. To perform this magic, hfs_format() may be
passed an array of block numbers to spare. These numbers must
correspond to logical 512-byte blocks on the device and should be
relative to the beginning of the volume's partition, if any. If no
blocks need to be spared, 0 should be passed for `nbadblocks', and
`badblocks' may be a NULL pointer. Note that an error can occur if a
bad block occurs in a critical disk structure, or if there are too
many bad blocks (more than 25%) in the volume.
It is possible to map out or "spare" bad blocks on the device such that
the file system will be made aware of these blocks and will not attempt
to use them to store data. To perform this magic, hfs_format() may be
passed an array of block numbers to spare. These numbers must
correspond to logical 512-byte blocks on the device and should be
relative to the beginning of the volume's partition, if any. If no
blocks need to be spared, 0 should be passed for `nbadblocks', and
`badblocks' may be a NULL pointer. Note that an error can occur if a
bad block occurs in a critical disk structure, or if there are too
many bad blocks (more than 25%) in the volume.
If an error occurs, this function returns -1. Otherwise it returns 0.
If an error occurs, this function returns -1. Otherwise it returns 0.
===============================================================================

181
main.c
View File

@ -36,7 +36,7 @@ static PyObject *wrap_flush(PyObject *self, PyObject *args)
return Py_None;
}
static PyObject *wrap_flushall(PyObject *self)
static PyObject *wrap_flushall(PyObject *self, PyObject *args)
{
hfs_flushall();
return Py_None;
@ -52,7 +52,7 @@ static PyObject *wrap_umount(PyObject *self, PyObject *args)
return Py_None;
}
static PyObject *wrap_umountall(PyObject *self)
static PyObject *wrap_umountall(PyObject *self, PyObject *args)
{
hfs_umountall();
return Py_None;
@ -128,9 +128,9 @@ static PyObject *wrap_setcwd(PyObject *self, PyObject *args)
static PyObject *wrap_dirinfo(PyObject *self, PyObject *args) // returns name in bytes object!
{
hfsvol *arg_vol; PyObject *arg_vol_c; long argret_id;
long ret_id; char ret_name[32];
if(!PyArg_ParseTuple(args, "Ol", &arg_vol_c, &argret_id)) return NULL;
hfsvol *arg_vol; PyObject *arg_vol_c; unsigned long argret_id;
char ret_name[32];
if(!PyArg_ParseTuple(args, "Ok", &arg_vol_c, &argret_id)) return NULL;
if(arg_vol_c == Py_None) arg_vol = NULL;
else if(!(arg_vol = PyCapsule_GetPointer(arg_vol_c, NAME_HFSVOL))) return NULL;
if(hfs_dirinfo(arg_vol, &argret_id, ret_name)) return NULL;
@ -140,7 +140,6 @@ static PyObject *wrap_dirinfo(PyObject *self, PyObject *args) // returns name in
static PyObject *wrap_opendir(PyObject *self, PyObject *args)
{
hfsvol *arg_vol; PyObject *arg_vol_c; char *arg_path;
hfsdir *ret_dir;
if(!PyArg_ParseTuple(args, "Oy", &arg_vol_c, &arg_path)) return NULL;
if(arg_vol_c == Py_None) arg_vol = NULL;
else if(!(arg_vol = PyCapsule_GetPointer(arg_vol_c, NAME_HFSVOL))) return NULL;
@ -149,18 +148,18 @@ static PyObject *wrap_opendir(PyObject *self, PyObject *args)
static PyObject *wrap_readdir(PyObject *self, PyObject *args)
{
hfsvol *arg_dir; PyObject *arg_dir_c;
hfsdir *arg_dir; PyObject *arg_dir_c;
hfsdirent ret_ent;
if(!PyArg_ParseTuple(args, "O", &arg_dir_c)) return NULL;
if(arg_dir_c == Py_None) arg_dir = NULL;
else if(!(arg_dir = PyCapsule_GetPointer(arg_dir_c, NAME_HFSDIR))) return NULL;
if(hfs_readdir(arg_dir, &ret_dirent)) return NULL;
return Py_BuildValue("y#", (char *)(&ret_dirent), sizeof(ret_dirent));
if(hfs_readdir(arg_dir, &ret_ent)) return NULL;
return Py_BuildValue("y#", (char *)(&ret_ent), sizeof(ret_ent));
}
static PyObject *wrap_closedir(PyObject *self, PyObject *args)
{
hfsvol *arg_dir; PyObject *arg_dir_c;
hfsdir *arg_dir; PyObject *arg_dir_c;
if(!PyArg_ParseTuple(args, "O", &arg_dir_c)) return NULL;
if(arg_dir_c == Py_None) arg_dir = NULL;
else if(!(arg_dir = PyCapsule_GetPointer(arg_dir_c, NAME_HFSDIR))) return NULL;
@ -191,7 +190,7 @@ static PyObject *wrap_open(PyObject *self, PyObject *args)
static PyObject *wrap_setfork(PyObject *self, PyObject *args)
{
hfsvol *arg_file; PyObject *arg_file_c; int arg_fork;
hfsfile *arg_file; PyObject *arg_file_c; int arg_fork;
if(!PyArg_ParseTuple(args, "Oi", &arg_file_c, &arg_fork)) return NULL;
if(arg_file_c == Py_None) arg_file = NULL;
else if(!(arg_file = PyCapsule_GetPointer(arg_file_c, NAME_HFSFILE))) return NULL;
@ -201,8 +200,8 @@ static PyObject *wrap_setfork(PyObject *self, PyObject *args)
static PyObject *wrap_getfork(PyObject *self, PyObject *args)
{
hfsvol *arg_file; PyObject *arg_file_c;
if(!PyArg_ParseTuple(args, "O", &arg_file_c, &arg_fork)) return NULL;
hfsfile *arg_file; PyObject *arg_file_c;
if(!PyArg_ParseTuple(args, "O", &arg_file_c)) return NULL;
if(arg_file_c == Py_None) arg_file = NULL;
else if(!(arg_file = PyCapsule_GetPointer(arg_file_c, NAME_HFSFILE))) return NULL;
return Py_BuildValue("i", hfs_getfork(arg_file));
@ -210,7 +209,7 @@ static PyObject *wrap_getfork(PyObject *self, PyObject *args)
static PyObject *wrap_read(PyObject *self, PyObject *args) // pass in a bytearray and get it shrunk!
{
hfsvol *arg_file; PyObject *arg_file_c; PyObject *arg_bytearray;
hfsfile *arg_file; PyObject *arg_file_c; PyObject *arg_bytearray;
if(!PyArg_ParseTuple(args, "OY", &arg_file_c, &arg_bytearray)) return NULL;
if(arg_file_c == Py_None) arg_file = NULL;
else if(!(arg_file = PyCapsule_GetPointer(arg_file_c, NAME_HFSFILE))) return NULL;
@ -222,7 +221,7 @@ static PyObject *wrap_read(PyObject *self, PyObject *args) // pass in a bytearra
static PyObject *wrap_write(PyObject *self, PyObject *args) // pass in a bytearray and get it shrunk!
{
hfsvol *arg_file; PyObject *arg_file_c; PyObject *arg_bytes; Py_ssize_t arg_bytes_len;
hfsfile *arg_file; PyObject *arg_file_c; PyObject *arg_bytes; Py_ssize_t arg_bytes_len;
if(!PyArg_ParseTuple(args, "Oy#", &arg_file_c, &arg_bytes, &arg_bytes_len)) return NULL;
if(arg_file_c == Py_None) arg_file = NULL;
else if(!(arg_file = PyCapsule_GetPointer(arg_file_c, NAME_HFSFILE))) return NULL;
@ -233,7 +232,7 @@ static PyObject *wrap_write(PyObject *self, PyObject *args) // pass in a bytearr
static PyObject *wrap_truncate(PyObject *self, PyObject *args) // pass in a bytearray and get it shrunk!
{
hfsvol *arg_file; PyObject *arg_file_c; unsigned long *arg_len;
hfsfile *arg_file; PyObject *arg_file_c; unsigned long arg_len;
if(!PyArg_ParseTuple(args, "Ok", &arg_file_c, &arg_len)) return NULL;
if(arg_file_c == Py_None) arg_file = NULL;
else if(!(arg_file = PyCapsule_GetPointer(arg_file_c, NAME_HFSFILE))) return NULL;
@ -243,7 +242,7 @@ static PyObject *wrap_truncate(PyObject *self, PyObject *args) // pass in a byte
static PyObject *wrap_seek(PyObject *self, PyObject *args) // pass in a bytearray and get it shrunk!
{
hfsvol *arg_file; PyObject *arg_file_c; long *arg_offset; int arg_from;
hfsfile *arg_file; PyObject *arg_file_c; long arg_offset; int arg_from;
if(!PyArg_ParseTuple(args, "Oli", &arg_file_c, &arg_offset, &arg_from)) return NULL;
if(arg_file_c == Py_None) arg_file = NULL;
else if(!(arg_file = PyCapsule_GetPointer(arg_file_c, NAME_HFSFILE))) return NULL;
@ -254,14 +253,132 @@ static PyObject *wrap_seek(PyObject *self, PyObject *args) // pass in a bytearra
static PyObject *wrap_close(PyObject *self, PyObject *args) // pass in a bytearray and get it shrunk!
{
hfsvol *arg_file; PyObject *arg_file_c;
if(!PyArg_ParseTuple(args, "O", &arg_file_c, &arg_offset, &arg_from)) return NULL;
hfsfile *arg_file; PyObject *arg_file_c;
if(!PyArg_ParseTuple(args, "O", &arg_file_c)) return NULL;
if(arg_file_c == Py_None) arg_file = NULL;
else if(!(arg_file = PyCapsule_GetPointer(arg_file_c, NAME_HFSFILE))) return NULL;
if(hfs_close(arg_file, arg_offset, arg_from)) return NULL;
if(hfs_close(arg_file)) return NULL;
return Py_None;
}
static PyObject *wrap_stat(PyObject *self, PyObject *args)
{
hfsvol *arg_vol; PyObject *arg_vol_c; char *arg_path;
hfsdirent ret_ent;
if(!PyArg_ParseTuple(args, "Oy", &arg_vol_c, &arg_path)) return NULL;
if(arg_vol_c == Py_None) arg_vol = NULL;
else if(!(arg_vol = PyCapsule_GetPointer(arg_vol_c, NAME_HFSVOL))) return NULL;
if(hfs_stat(arg_vol, arg_path, &ret_ent)) return NULL;
return Py_BuildValue("y#", (char *)(&ret_ent), sizeof(ret_ent));
}
static PyObject *wrap_fstat(PyObject *self, PyObject *args)
{
hfsfile *arg_file; PyObject *arg_file_c;
hfsdirent ret_ent;
if(!PyArg_ParseTuple(args, "O", &arg_file_c)) return NULL;
if(arg_file_c == Py_None) arg_file = NULL;
else if(!(arg_file = PyCapsule_GetPointer(arg_file_c, NAME_HFSFILE))) return NULL;
if(hfs_fstat(arg_file, &ret_ent)) return NULL;
return Py_BuildValue("y#", (char *)(&ret_ent), sizeof(ret_ent));
}
static PyObject *wrap_setattr(PyObject *self, PyObject *args)
{
hfsvol *arg_vol; PyObject *arg_vol_c; char *arg_path; hfsdirent *arg_ent; Py_ssize_t arg_ent_len;
if(!PyArg_ParseTuple(args, "Oyy#", &arg_vol_c, &arg_path, &arg_ent, &arg_ent_len)) return NULL;
if(arg_ent_len != sizeof(*arg_ent)) return NULL;
if(arg_vol_c == Py_None) arg_vol = NULL;
else if(!(arg_vol = PyCapsule_GetPointer(arg_vol_c, NAME_HFSVOL))) return NULL;
if(hfs_setattr(arg_vol, arg_path, arg_ent)) return NULL;
return Py_None;
}
static PyObject *wrap_fsetattr(PyObject *self, PyObject *args)
{
hfsfile *arg_file; PyObject *arg_file_c; hfsdirent *arg_ent; Py_ssize_t arg_ent_len;
if(!PyArg_ParseTuple(args, "Oy#", &arg_file_c, &arg_ent, &arg_ent_len)) return NULL;
if(arg_ent_len != sizeof(*arg_ent)) return NULL;
if(arg_file_c == Py_None) arg_file = NULL;
else if(!(arg_file = PyCapsule_GetPointer(arg_file_c, NAME_HFSFILE))) return NULL;
if(hfs_fsetattr(arg_file, arg_ent)) return NULL;
return Py_None;
}
static PyObject *wrap_mkdir(PyObject *self, PyObject *args)
{
hfsvol *arg_vol; PyObject *arg_vol_c; char *arg_path;
if(!PyArg_ParseTuple(args, "Oy", &arg_vol_c, &arg_path)) return NULL;
if(arg_vol_c == Py_None) arg_vol = NULL;
else if(!(arg_vol = PyCapsule_GetPointer(arg_vol_c, NAME_HFSVOL))) return NULL;
if(hfs_mkdir(arg_vol, arg_path)) return NULL;
return Py_None;
}
static PyObject *wrap_rmdir(PyObject *self, PyObject *args)
{
hfsvol *arg_vol; PyObject *arg_vol_c; char *arg_path;
if(!PyArg_ParseTuple(args, "Oy", &arg_vol_c, &arg_path)) return NULL;
if(arg_vol_c == Py_None) arg_vol = NULL;
else if(!(arg_vol = PyCapsule_GetPointer(arg_vol_c, NAME_HFSVOL))) return NULL;
if(hfs_rmdir(arg_vol, arg_path)) return NULL;
return Py_None;
}
static PyObject *wrap_delete(PyObject *self, PyObject *args)
{
hfsvol *arg_vol; PyObject *arg_vol_c; char *arg_path;
if(!PyArg_ParseTuple(args, "Oy", &arg_vol_c, &arg_path)) return NULL;
if(arg_vol_c == Py_None) arg_vol = NULL;
else if(!(arg_vol = PyCapsule_GetPointer(arg_vol_c, NAME_HFSVOL))) return NULL;
if(hfs_delete(arg_vol, arg_path)) return NULL;
return Py_None;
}
static PyObject *wrap_rename(PyObject *self, PyObject *args)
{
hfsvol *arg_vol; PyObject *arg_vol_c; char *arg_srcpath; char *arg_dstpath;
if(!PyArg_ParseTuple(args, "Oy", &arg_vol_c, &arg_srcpath, &arg_dstpath)) return NULL;
if(arg_vol_c == Py_None) arg_vol = NULL;
else if(!(arg_vol = PyCapsule_GetPointer(arg_vol_c, NAME_HFSVOL))) return NULL;
if(hfs_rename(arg_vol, arg_srcpath, arg_dstpath)) return NULL;
return Py_None;
}
static PyObject *wrap_zero(PyObject *self, PyObject *args)
{
char *arg_path; unsigned int arg_maxparts;
unsigned long ret_blocks;
if(!PyArg_ParseTuple(args, "sI", &arg_path, &arg_maxparts)) return NULL;
if(hfs_zero(arg_path, arg_maxparts, &ret_blocks)) return NULL;
return Py_BuildValue("k", ret_blocks);
}
static PyObject *wrap_mkpart(PyObject *self, PyObject *args)
{
char *arg_path; unsigned long arg_len;
if(!PyArg_ParseTuple(args, "sk", &arg_path, &arg_len)) return NULL;
if(hfs_mkpart(arg_path, arg_len)) return NULL;
return Py_None;
}
static PyObject *wrap_nparts(PyObject *self, PyObject *args)
{
char *arg_path;
int ret;
if(!PyArg_ParseTuple(args, "s", &arg_path)) return NULL;
ret = hfs_nparts(arg_path);
if(ret == -1) return NULL;
return Py_BuildValue("i", ret);
}
static PyObject *wrap_format(PyObject *self, PyObject *args) // bad blocks unimplemented
{
char *arg_path; int arg_pnum; int arg_mode; char *arg_vname;
if(!PyArg_ParseTuple(args, "siiy", &arg_path, &arg_pnum, &arg_mode, &arg_vname)) return NULL;
if(hfs_format(arg_path, arg_pnum, arg_mode, arg_vname, 0, NULL)) return NULL;
return Py_None;
}
static PyMethodDef module_methods[] = {
@ -294,19 +411,19 @@ static PyMethodDef module_methods[] = {
{"seek", wrap_seek, METH_VARARGS, ""},
{"close", wrap_close, METH_VARARGS, ""},
// Catalog routines
// {"stat", wrap_stat, METH_VARARGS, ""},
// {"fstat", wrap_fstat, METH_VARARGS, ""},
// {"setattr", wrap_setattr, METH_VARARGS, ""},
// {"fsetattr", wrap_fsetattr, METH_VARARGS, ""},
// {"mkdir", wrap_mkdir, METH_VARARGS, ""},
// {"rmdir", wrap_rmdir, METH_VARARGS, ""},
// {"delete", wrap_delete, METH_VARARGS, ""},
// {"rename", wrap_rename, METH_VARARGS, ""},
{"stat", wrap_stat, METH_VARARGS, ""},
{"fstat", wrap_fstat, METH_VARARGS, ""},
{"setattr", wrap_setattr, METH_VARARGS, ""},
{"fsetattr", wrap_fsetattr, METH_VARARGS, ""},
{"mkdir", wrap_mkdir, METH_VARARGS, ""},
{"rmdir", wrap_rmdir, METH_VARARGS, ""},
{"delete", wrap_delete, METH_VARARGS, ""},
{"rename", wrap_rename, METH_VARARGS, ""},
// Media routines
// {"zero", wrap_zero, METH_VARARGS, ""},
// {"mkpart", wrap_mkpart, METH_VARARGS, ""},
// {"nparts", wrap_nparts, METH_VARARGS, ""},
// {"format", wrap_format, METH_VARARGS, ""},
{"zero", wrap_zero, METH_VARARGS, ""},
{"mkpart", wrap_mkpart, METH_VARARGS, ""},
{"nparts", wrap_nparts, METH_VARARGS, ""},
{"format", wrap_format, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};