###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).

* <a href="./#open_archive">Open a SAP archive</a>
* <a href="./#create_archive">Create a SAP archive</a>
* <a href="./#close_archive">Close a SAP archive</a>
* <a href="./#fill_archive">Fill a SAP archive</a>
* <a href="./#read_sector">Read a SAP sector</a>
* <a href="./#read_sectors">Read a range of SAP sectors</a>
* <a href="./#write_sector">Write a SAP sector</a>
* <a href="./#write_sectors">Write a range of SAP sectors</a>
* <a href="./#format_archive">Format a SAP archive</a>
* <a href="./#list_archive">Store the directory of a SAP archive</a>
* <a href="./#add_file">Add a file to a SAP archive</a>
* <a href="./#delete_file">Delete a file in a SAP archive</a>
* <a href="./#exract_file">Extract a file from a SAP archive</a>
* <a href="./#read_informations">Get informations of a SAP file</a>

#####Open a SAP archive<a name="open_archive"></a>

<b><i>sapID sap\_OpenArchive(const char filename\[\], int \*format);</i></b><br><span style="padding-left:30px">*filename : name of the SAP archive*</span><br><span style="padding-left:30px">*format : return of the archive format (SAP\_FORMAT1 or SAP\_FORMAT2)*</span>

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<a name="create_archive"></a>

<b><i>sapID sap\_CreateArchive(const char filename\[\], int format);</i></b><br><span style="padding-left:30px">*filename : name of the SAP archive*</span><br><span style="padding-left:30px">*format : archive format (SAP\_FORMAT1 or SAP\_FORMAT2)*</span>

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<a name="close_archive"></a>

<b><i>int sap\_CloseArchive(sapID id);</i></b><br>
<span style="padding-left:30px">*id : identifier of the SAP archive*</span>

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<a name="fill_archive"></a>

<b><i>int sap\_FillArchive(sapID id, sapsector\_t \*sapsector);</i></b><br><span style="padding-left:30px">*id : identifier of the SAP archive*</span><br><span style="padding-left:30px">*sapsector : pointer to a sector structure*</span>

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<a name="read_sector"></a>

<b><i>int sap\_ReadSector(sapID id, int track, int sect, sapsector\_t \*sapsector);</i></b><br><span style="padding-left:30px">*id : identifier of the SAP archive*</span><br><span style="padding-left:30px">*track : track number*</span><br><span style="padding-left:30px">*sect : sector number*</span><br><span style="padding-left:30px">*sapsector : pointer to a sector structure*</span>

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<a name="read_sectors"></a>

<b><i>int sap\_ReadSectorEx(sapID id, int track, int sect, int nsects, unsigned char data\[\]);</i></b><br><span style="padding-left:30px">*id : identifier of the SAP archive*</span><br><span style="padding-left:30px">*track : track number to start from*</span><br><span style="padding-left:30px">*sect : sector number to start from*</span><br><span style="padding-left:30px">*nsect : number of sectors to read*</span><br><span style="padding-left:30px">*data : buffer large enough to store sectors*</span>

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<a name="write_sector"></a>

<b><i>int sap\_WriteSector(sapID id, int track, int sect, sapsector\_t \*sapsector);</i></b><br><span style="padding-left:30px">*id : identifier of the SAP archive*</span><br><span style="padding-left:30px">*track : track number*</span><br><span style="padding-left:30px">*sect : sector number*</span><br><span style="padding-left:30px">*sapsector : pointer to a sector structure*</span>

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<a name="write_sectors"></a>

<b><i>int sap\_WriteSectorEx(sapID id, int track, int sect, int nsects, const unsigned char data\[\]);</i></b><br><span style="padding-left:30px">*id : identifier of the SAP archive*</span><br><span style="padding-left:30px">*track : track number to start from*</span><br><span style="padding-left:30px">*sect : sector number to start from*</span><br><span style="padding-left:30px">*nsect : number of sectors to write*</span><br><span style="padding-left:30px">*data : buffer of sectors*</span>

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<a name="format_archive"></a>

<b><i>int sap\_FormatArchive(sapID id, int capacity);</i></b><br><span style="padding-left:30px">*id : identifier of the SAP archive*</span><br><span style="padding-left:30px">*capacity : SAP\_TRK80 (80 tracks) or SAP\_TRK40 (40 tracks)*</span>

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<a name="list_archive"></a>

<b><i>int sap\_ListArchive(sapID id, char buffer\[\], int buffer\_size);</i></b><br><span style="padding-left:30px">*id : identifier of the SAP archive*</span><br><span style="padding-left:30px">*buffer : buffer for list of files*</span><br><span style="padding-left:30px">*buffer\_size : size of buffer*</span>

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<a name="add_file"></a>

<b><i>int sap\_AddFile(sapID id, const char filename\[\]);</i></b><br><span style="padding-left:30px">*id : identifier of the SAP archive*</span><br><span style="padding-left:30px">*filename : name of the file to add*</span>

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<a name="delete_file"></a>

<b><i>int sap\_DeleteFile(sapID id, const char pattern\[\]);</i></b><br><span style="padding-left:30px">*id : identifier of the SAP archive*</span><br><span style="padding-left:30px">*pattern : pattern of the file(s) to delete ('\*' and '?' are supported)*</span>

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<a name="exract_file"></a>

<b><i>int sap\_ExtractFile(sapID id, const char pattern\[\]);</i></b><br><span style="padding-left:30px">*id : identifier of the SAP archive*</span><br><span style="padding-left:30px">*pattern : pattern of the file(s) to extract ('\*' and '?' are supported)*</span>

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<a name="read_informations"></a>

<b><i>int sap\_GetFileInfo(sapID id, const char filename\[\], sapfileinfo\_t \*info);</i></b><br><span style="padding-left:30px">*id : identifier of the SAP archive*</span><br><span style="padding-left:30px">*filename : name of the file to examine*</span>

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.

