LibSAP

LibSAP is a library for handling SAP archives written in ANSI C. It provides both low-level routines handling SAP archives considered as physical format (disk images) and high-level routines handling SAP archives considered as logic format (compatible with DOS BASIC Thomson).

Open a SAP archive

sapID sap_OpenArchive(const char filename[], int *format);
filename : name of the SAP archive
format : return of the archive format (SAP_FORMAT1 or SAP_FORMAT2)

Returns the identifier of the SAP archive. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_ETOOMANY : too many SAP archives are opened simultaneously. SAP_ENOENT : specified SAP archive does not exist. SAP_EBADF : The specified file is not a SAP archive.

Create a SAP archive

sapID sap_CreateArchive(const char filename[], int format);
filename : name of the SAP archive
format : archive format (SAP_FORMAT1 or SAP_FORMAT2)

Returns the identifier of the SAP archive. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_ETOOMANY : too many SAP archives are opened simultaneously. SAP_EPERM : Can not create file on the recording medium.

Close a SAP archive

int sap_CloseArchive(sapID id);
id : identifier of the SAP archive

Returns SAP_OK. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_EINVAL : SAP archive identifier (SAPID) is invalid.

Fill a SAP archive

int sap_FillArchive(sapID id, sapsector_t *sapsector);
id : identifier of the SAP archive
sapsector : pointer to a sector structure

Fills an archive created by sap_CreateArchive() sector by sector, starting from sector 1 of track 0. At each call, the sector number is incremented by 1 and, if the current track becomes full, the next track is selected. Returns SAP_OK. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_EINVAL : SAP archive identifier (SAPID) is invalid. SAP_ENOSPC : SAP archive is full.

Read a SAP sector

int sap_ReadSector(sapID id, int track, int sect, sapsector_t *sapsector);
id : identifier of the SAP archive
track : track number
sect : sector number
sapsector : pointer to a sector structure

The result is in the structure sapsector. Returns SAP_OK flags or a combination of the following codes: SAP_NO_STD_FMT : the format is non-standard sector. SAP_PROTECTED : the sector is write protected. SAP_BAD_SECTOR : the sector has bad identifiers (track, sector) SAP_CRC_ERROR : CRC error on data sector.

On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_EINVAL : SAP archive identifier (SAPID) is invalid. SAP_EEMPTY : SAP archive is empty. SAP_EBUSY : archive the SAP is being filled by sap_FillArchive()

Read a range of SAP sectors

int sap_ReadSectorEx(sapID id, int track, int sect, int nsects, unsigned char data[]);
id : identifier of the SAP archive
track : track number to start from
sect : sector number to start from
nsect : number of sectors to read
data : buffer large enough to store sectors

Returns SAP_OK. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_EINVAL : SAP archive identifier (SAPID) is invalid. SAP_EEMPTY : SAP archive is empty. SAP_EBUSY : SAP archive is being filled by sap_FillArchive()

Write a SAP sector

int sap_WriteSector(sapID id, int track, int sect, sapsector_t *sapsector);
id : identifier of the SAP archive
track : track number
sect : sector number
sapsector : pointer to a sector structure

All fields in the sector must be specified, except the two fields for the CRC which will be calculated by the routine itself. Returns SAP_OK. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_EINVAL : SAP archive identifier (SAPID) is invalid. SAP_EEMPTY : SAP archive is empty. SAP_EBUSY : SAP archive is being filled by sap_FillArchive()

Write a range of SAP sectors

int sap_WriteSectorEx(sapID id, int track, int sect, int nsects, const unsigned char data[]);
id : identifier of the SAP archive
track : track number to start from
sect : sector number to start from
nsect : number of sectors to write
data : buffer of sectors

Returns SAP_OK. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_EINVAL : SAP archive identifier (SAPID) is invalid. SAP_EEMPTY : SAP archive is empty. SAP_EBUSY : SAP archive is being filled by sap_FillArchive()

Format a SAP archive

int sap_FormatArchive(sapID id, int capacity);
id : identifier of the SAP archive
capacity : SAP_TRK80 (80 tracks) or SAP_TRK40 (40 tracks)

Returns SAP_OK. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_EINVAL : SAP archive identifier (SAPID) is invalid. SAP_EBUSY : SAP archive is being filled by sap_FillArchive()

Store the directory of a SAP archive

int sap_ListArchive(sapID id, char buffer[], int buffer_size);
id : identifier of the SAP archive
buffer : buffer for list of files
buffer_size : size of buffer

Returns the number of lines of the list. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_EINVAL : SAP archive identifier (SAPID) is invalid. SAP_EEMPTY : SAP archive is empty. SAP_EBUSY : SAP archive is being filled by sap_FillArchive()

Add a file to a SAP archive

int sap_AddFile(sapID id, const char filename[]);
id : identifier of the SAP archive
filename : name of the file to add

Returns the size of the file added in bytes. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_EINVAL : SAP archive identifier (SAPID) is invalid. SAP_EEMPTY : SAP archive is empty. SAP_EBUSY : SAP archive is being filled by sap_FillArchive() SAP_ENOENT : the file does not exist. SAP_ENFILE : the file is empty. SAP_ENOSPC : the SAP archive directory is full. SAP_EFBIG : the file is too big compared with the free space of the SAP archive.

Delete a file in a SAP archive

int sap_DeleteFile(sapID id, const char pattern[]);
id : identifier of the SAP archive
pattern : pattern of the file(s) to delete ('*' and '?' are supported)

Returns the size of the file(s) deleted in bytes. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_EINVAL : SAP archive identifier (SAPID) is invalid. SAP_EEMPTY : SAP archive is empty. SAP_EBUSY : SAP archive is being filled by sap_FillArchive() SAP_ENOENT : the file does not exist.

Extract a file from a SAP archive

int sap_ExtractFile(sapID id, const char pattern[]);
id : identifier of the SAP archive
pattern : pattern of the file(s) to extract ('*' and '?' are supported)

Returns the size of the file(s) extracted in bytes. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_EINVAL : SAP archive identifier (SAPID) is invalid. SAP_EEMPTY : SAP archive is empty. SAP_EBUSY : SAP archive is being filled by sap_FillArchive() SAP_ENOENT : the file does not exist in the SAP archive (invalid error when pattern contains at least one wildcard). SAP_EPERM : Can not write the file to the media.

Get informations of a SAP file

int sap_GetFileInfo(sapID id, const char filename[], sapfileinfo_t *info);
id : identifier of the SAP archive
filename : name of the file to examine

Returns SAP_OK. On failure, SAP_ERROR is returned and the 'sap_errno' variable is set to one of the following error codes: SAP_EINVAL : SAP archive identifier (SAPID) is invalid. SAP_EEMPTY : SAP archive is empty. SAP_EBUSY : SAP archive is being filled by sap_FillArchive() SAP_ENOENT : the file does not exist.