/* FILE.H - file interface definitions - with networking */ #define KEYFIELDS 6 /* max number of fields in a key */ struct key_parms { /* key parameters for split key capability */ short int fkeyposn; /* position of key in record-key files only */ unsigned char fkeylen, /* key length - for key files only */ fkeyucase; /* force upper case */ }; /* internal file control byte (delete code) format */ #define BCLEAR 0x20 /* clear - no flags, not deleted */ #define BDELETE 0x44 /* hex for 'D' */ #define BNOFLOW 0x01 /* no keys in overflow between this and previous key */ #define BNODUP 0x02 /* no duplicate key previous */ #define MAXPTABLE 10 /* max number of printer tables. 0 default 9 named */ /* bfcb BASIC FILE CONTROL BLOCK */ struct bfcb { long flast, /* last record number used - end of file */ fsort; /* last sorted record - key file only */ unsigned char ftype; /* 4-internal, 9 program */ /* 5 - display file */ /* 7 - Btree index */ /* 'A' - async communications file */ /* 128 - screen, 192 - keyboard, 255 - printer */ short int freclen, /* record length (if display file- buflen) or for internal is recl+1, or if screen- max row/col excl status line base 0 */ foffset; /* offset bytes to first record or screen escape code attribute base */ unsigned char fkeys, /* number of keys per record (split keys) */ fflags; /* key file collate option */ /* 0x0F: 0 - native, 1 - alternate, 2-s23 ebcidic */ /* 0x10 - key search is case insensitive Also loaded into fucase */ /* 0x20 - linked file, using deleted record chain */ /* all fields above are kept on internal and index files */ long int freserve, /* file is reserved - semaphore handle */ fnext; /* current position of file - used by file driver only */ int (*fdriver)(); /* pointer to driver function for file */ short int fwrtcnt, /* number of records added since file was opened */ ffd; /* file descriptor - used by driver only */ unsigned char fname[67], /* file path name */ fnetwork, /* network id */ fdrive; /* universial drive reference */ struct bfcb *nextbfcb; /* next bfcb in horizontal chain */ unsigned char *kmarkedl, /* last key marked for overflow */ *kmarkedu, /* last key marked for overflow */ *kw; /* key work space pointer */ /* or communications receive buffer. first two bytes of the buffer contain the length of the buffer, excluding the first two bytes (alloc bufsize+2) */ struct key_parms *fkparms; /* pointer to key parameters */ /* see struct key_parms above */ /* these structures follow fkeys on disk */ int fcreate, /* set to 1 if file was created at open time */ fio, /* 0 - if file is opened read only */ fcnt; /* number of ufcbs using this bfcb */ struct ufcb *fufnext; /* pointer to keyed ufcb's using this bfcb as master*/ unsigned int fbaud; /* also used for CLOSE,FREE to pass OP to file.c */ int fparity, /* also used as linked flag */ fdatabits, fstopbits, /* also used as wait count for OPEN */ fucase, /* ignore case flag for key files (see fflags) */ fcollate, /* key file collate option (see fflags) */ chyron; long flastpos, /* last position in file (flastpos=lseek(fd,0L,2) */ fdelchain; /* pointer to first deleted record */ #ifdef S23 unsigned char fs23name[34]; /* system 23 name for file$ */ #endif }; #define ftotalkeylen chyron /* sum of keyparts , add to bfcb later */ /* ufcb USER FILE CONTROL BLOCK */ struct rowcol { #ifdef LO_HI unsigned char col, row; #else short int dummyxx; unsigned char row, col; #endif }; union row_col { #ifdef LO_HI struct rowcol rc; short int rcpos; #else struct rowcol rc; int rcpos; #endif } ; struct ufcb { short int ufreclen, /* record length - duplicate from freclen */ /* for internal files, is freclen-1 */ ufwrtcnt, /* internal - varies */ /* display - page over flow count */ /* screen - last position for this window */ ufbuffpos; /* WSBASIC current position in buffer (base 0) or cursor position for screen or last scancode/character keyed */ unsigned int ufreadlen; /* equals ufreclen for external, = freclen+1 for int */ int ufclose_on_end, /* 1=close file on stop/end/chain (default) */ uflpp, /* lines per page */ ufconv; /* character to use if conversion error */ unsigned char ufnbr, /* basic logical file number if 0 - terminal if 128 - keyboard */ ufshare, /* share status 0 - 4 */ ufmode, /* 0 - sequential */ /* 1 - relative */ /* 2 - keyed, 3 - 2 key files, 4 - 3 key files, etc */ uftype, /* usually same as ftype */ uferror, /* used by FILE(x) */ ufopen, /* 1 - open input 2 - open output 3 - open input/output */ ufstatus; /* 0 - ready for read at current recnbr 1 - record has been read, valid for reread or rewrite 2 - record has been written or rewritten 3 - error If screen file this is scroll status (&0x80) */ struct bfcb *ufbfcb, /* pointer to bfcbs, master and key */ *ufkbfcb; struct ufcb *nextufcb; /* chain of ufcb's for this user (anchored in tcb) */ struct bstring *ufbuffer; /* record buffer pointer, first two bytes (int) of the buffer is used to hold bytes read/written */ unsigned char *uftable; /* pointer to translation table */ /* the following elements may be accessed as uf->name instead of uf->uf_.uff.name. The defines below will translate them. */ union { struct { long _ufcurrent, /* last record (or byte) accessed this session */ _sread_rec, /* save ufcurrent for key reads */ _ufkcurrent, /* last key record accessed, or first link */ _ufsemaphore, /* network semaphore handle */ _ufksemaphore, /* network semaphore handle, or link main rec# */ *_uflocked, /* pointer to array of locked records. In array: -1 - empty, -2 - All records locked, or position of locked record */ _uflinknext, /* next record pointer for linked lists */ _uflinkprev; /* previous record pointer for linked lists */ int _sreadstatus, /* flag for keyed restore */ _uflockcnt, /* maximum number of items in uflocked */ _ufwait, /* how many seconds to wait for locked record */ _uflockflag, /* 0, or >0 if record locking required for this file */ /* number of bytes to be locked for each record */ _ufsave_lockflag, /* save lockflag while RESERVE locks all records */ _ufrr, /* set to 0 (default), RESERVE or RELEASE */ /* also used as ufprn_table with display files */ _ufpos, /* external last used: 0 - rec, 1 - pos */ /* also used as ufinit_flag with display files */ _ufformat, /* if 'A' - async communications file */ _ufeol, /* specifies eol character */ _ufretry, /* number of times to retry a transmission */ _uflinked; /* linked flag */ struct bstring *_ufwbuffer, /* location of rewrite buffer */ *_ufkey; /* pointer to key, for read by key */ unsigned char *_uflastkey, /* lastkey work area */ *_ufkw; /* key work area */ struct ufcb *_ufnext, /* other keyed ufcbs using the same master file*/ *_filler; /* delete on next wb build */ } uff; #define ufcurrent uf_.uff._ufcurrent #define sread_rec uf_.uff._sread_rec #define ufkcurrent uf_.uff._ufkcurrent #define ufsemaphore uf_.uff._ufsemaphore #define ufksemaphore uf_.uff._ufksemaphore #define uflocked uf_.uff._uflocked #define sreadstatus uf_.uff._sreadstatus #define uflockcnt uf_.uff._uflockcnt #define ufkey uf_.uff._ufkey #define ufwbuffer uf_.uff._ufwbuffer #define uflastkey uf_.uff._uflastkey #define ufkw uf_.uff._ufkw #define uflockflag uf_.uff._uflockflag #define ufsave_lockflag uf_.uff._ufsave_lockflag #define ufrr uf_.uff._ufrr #define ufprn_table uf_.uff._ufrr #define ufoflow uf_.uff._ufoflow #define ufpos uf_.uff._ufpos #define ufinit_flag uf_.uff._ufpos #define ufwait uf_.uff._ufwait #define ufretry uf_.uff._ufretry #define ufformat uf_.uff._ufformat #define ufeol uf_.uff._ufeol #define ufnext uf_.uff._ufnext #define uflinked uf_.uff._uflinked #define uflinknext uf_.uff._uflinknext #define uflinkprev uf_.uff._uflinkprev struct { /* type 128 - screen files */ int _ufsaddress, _ufeaddress, _ufwidth, _ufnormal, _ufsrestore, /* starting address to restore */ _uferestore, /* ending address to restore */ _ufwrestore; /* width of restore */ union row_col /* may be .row, .col, .xpos (row/col) */ _ufsposn, _ufeposn; unsigned char _ufborder, /* flag, border type/if */ *_ufssave; int _ufmaxrow, /* window max row, base 0 */ _ufmaxcol, /* window col max, base 1 */ _uflinecnt; /* lines printed since last newpage */ } ufs; #define ufnormal uf_.ufs._ufnormal #define ufwidth uf_.ufs._ufwidth #define ufsaddress uf_.ufs._ufsaddress #define ufeaddress uf_.ufs._ufeaddress #define ufsrestore uf_.ufs._ufsrestore #define uferestore uf_.ufs._uferestore #define ufwrestore uf_.ufs._ufwrestore #define erow ufeposn.rc.row #define ecol ufeposn.rc.col #define srow ufsposn.rc.row #define scol ufsposn.rc.col #define ufsposn uf_.ufs._ufsposn #define ufeposn uf_.ufs._ufeposn #define ufborder uf_.ufs._ufborder #define ufssave uf_.ufs._ufssave #define ufmaxrow uf_.ufs._ufmaxrow #define ufmaxcol uf_.ufs._ufmaxcol #define uflinecnt uf_.ufs._uflinecnt } uf_; }; /* WSBASIC file module doesn't support action codes with a ++ in comment */ /* CAUTION: many of the following are relative to each other; FOPENC must be equal to FOPEN +1, KOPEN is FOPEN+8. Change with care! */ /* the following are called file(action,bfcb_pointer) */ #define FOPENE 0x10 /* Opens file for IO (input-output) */ #define FOPENN 0x11 /* NEW Creates file & opens for IO */ #define FOPENR 0x12 /* REPLACE Creates file, replaces any existing */ #define FOPENU 0x13 /* USE use existing file, or creates file if new */ #define KOPEN 0x18 /* Opens a key file for IO */ #define KOPENN 0x19 /* NEW Creates file & opens for IO */ #define KOPENR 0x1A /* REPLACE Creates file, replaces any existing */ #define KOPENU 0x1B /* USE use existing file, or creates file if new */ /* the following are called file(action,bfcb_pointer,semaphore) */ #define FCLOSE 0x20 /* Closes file */ #define KCLOSE 0x28 /* Close a key file */ /* the following are called file(action,bfcb_pointer) */ #define FDROP 0x30 /* Drops all data in file (retains record length) */ #define KDROP 0x38 /* Drops all keys in key file */ #define FFREE 0x40 /* Erases file from disk */ #define KFREE 0x48 /* Erases a key file from disk */ /* the following are called file(action,ufcb_pointer) */ #define FRESET 0x50 /* Restore to record at start of file */ #define FRESETLT 0x51 /* Restore to record less than */ #define FRESETLE 0x52 /* ++Restore to record less than or equal to */ #define FRESETEQ 0x53 /* Restore to record equal to */ #define FRESETGE 0x54 /* ++Restore to record equal or greater than */ #define FRESETLAST 0x55 /* ++Restore to record greater than */ #define CRESETEND 0x56 /* reset to end of file */ #define KRESET 0x58 /* Restore to key at start of file */ #define KRESETLT 0x59 /* ++Restore to key less than */ #define KRESETLE 0x5A /* ++Restore to key less than or equal to */ #define KRESETEQ 0x5B /* Restore to key equal to */ #define KRESETGE 0x5C /* Restore to key equal or greater than */ #define KRESETLAST 0x5D /* reset to last record of key file */ #define FREADLT 0x61 /* Read previous record */ #define FREADLE 0x62 /* ++Read record less than or equal to */ #define FREADEQ 0x63 /* Read record equal to */ #define FREADGE 0x64 /* Read record equal to or greater than */ #define FREADLAST 0x65 /* Read last record */ #define FREADNX 0x66 /* Read Next record - sequential read */ #define CCREAD 0x67 /* Read sequential characters */ #define KREADSAME 0x68 /* Read last key read */ #define KREADLT 0x69 /* Read previous key */ #define KREADLE 0x6A /* ++Read key less than or equal to */ #define KREADEQ 0x6B /* Read key equal to */ #define KREADGE 0x6C /* Read key equal to or greater than */ #define KREADLAST 0x6D /* Read Last key */ #define KREADNX 0x6E /* Read Next key - sequential read */ #define FDELETE 0x76 /* Deletes current ufcb record */ #define KDELETE 0x7E /* Deletes current ufcb key & record */ #define FWRITEA 0x86 /* Adds a new record to end of file */ #define CWRITE 0x87 /* Write sequential characters */ #define FKWRITE 0x88 /* add new record - special for index.c */ #define KWRITE 0x8E /* Adds a new key & record to a file */ #define FREWRITE 0x96 /* Rewrites an existing record */ #define KREWRITE 0x9E /* Rewrites an existing key and record */ #define UFUNLOCK 0xA0 /* unlocks all records for a UFCB */ #define EOFPOS 0xA1 /* sets fnext to last position in file */ #define FEXISTS 0xA2 /* returns a 1 if the file exists */ #define LOCKALL 0xA3 /* RESERVE all records in a file */ #define UNLOCKALL 0xA4 /* RELEASE all records locked by RESERVE */ /* WSBASIC file module doesn't support action codes with a ++ in the comment If the function is successful, return a zero. OPEN If action code is FOPENN or KOPENN, create the file with record length ufreclen, or return an error number if the file exists. The field ufcurrent will contain the create size in bytes for the file. If the file being opened does not allow sharing, check the bfstatus. Return an error if the file type supported doesnot allow sharing and share is specified (a communications port might not allow sharing). The field fname is the file name as it appears in the open statement, and is terminated by a null (default formats will be expanded). If an error code is returned, the file must be closed if it was opened. The data and key bfcb's require the following to be set: flast -the last valid record number in the file. New records are be added at flast+1 (internal files). freclen -Record length of the file. (does not include hidden delete code if used). fkparms -for key bfcb's only, this is a pointer to a key_parms structure (or array of scructures is split keys) that defines the key length and position. The file driver will allocate the memory for the structure. The following fields are only used by the file driver, and can be redefined for use in custom drivers: fnext -current physical position of file fsort -last sorted record for WSBASIC index files foffset -is the offset in the file to data record #1 used by WSBASIC for Internal files. ffd -is the 'C' file descriptor used by WSBASIC driver. fdel -is a 1 if records were deleted this session. kw -is a pointer to key work space. The work space is allocated by the file driver. CLOSE Close must 'disconnect' the file from WSBASIC. It should update flast and fsort, and free kw space if allocated. DROP Drop will restore the file to the beginning and set flast to zero. The actual file space may or may not be freed. FREE Free erases the file from the media. The file should not, and must not be currently open (WSBASIC searches all open bfcb's for matching name). Free the key file if it is specified. The file name is fname. RESET - RESTORE Restore will set the ufcb so that the next sequential read will read the record or key as indicated by the restore. Return error 719 if a restore action code is invalid for your driver. return error NOKEY or NOREC if a valid record or key cannot be found. READ Read will read a record as specified by the action code, into the buffer pointed to by ufbuffer, starting with the third buffer position ( ufbuffer+2 ), up to freclen bytes. The actual number of bytes read must be placed in the first two bytes of ufbuffer (*(int *)ufbuffer=bytes). If read is successful, set ufcurrent (and ufkcurrent) to the record number of the record in ufbuffer, otherwise do not change it. Record ZERO is not a valid record number. CREAD reads a sequential file, treats ufcurrent as the byte position in the file (instead of record position) , and fills the buffer with characters for processing. The specific record to read for FREADNX - read next, depends on ufstatus and ufcurrent. UFSTATUS READ RECORD# Comments: 0 ufcurrent If record is invalid return NOREC error. 1 & 2 ufcurrent +1 Return EOF error at end of file. or next valid record or next sequential key if keyed 3 error - should never happen If Read is by Key , the key is found in the buffer pointed to by ufkey. The first two bytes of the buffer are the key variable length. Fields ufcurrent (and ufkcurrent) must be updated with the record number of the read. DELETE Delete will make the record number ufcurrent (and ufkcurrent) invalid for access. A read by rec or key to a deleted record will cause a norec or nokey error, and sequential reads will skip deleted records. WRITE Write will add a record to the end of the file (flast+1). The record is at ufbuffer+2 for freclen bytes. For CWRITE, the first two bytes of ufbuffer will be the variable length of the record and as for CREAD, ufcurrent is the byte position in the file. If for FWRITE, ufcurrent, the record number specified is not valid for write, return a DUPREC error, or NOREC if ufcurrent is greater than flast+1. Deleted records may be reused by specifying the record number. Update ufcurrent with the record number added. Return a EOF error if no space is available to save the record. If KWRITE, add the key as indicated by fkeylen and fkeyposn to the key file, and the data record to flast+1 (KWRITE doesnot look at ufcurrent to determine where to add record). REWRITE Rewrite will write the record in ufbuffer over an existing record, ufcurrent. If (for KREWRITE) the key field has been modified, and if it is illegal for your key access, return a MODIFIED KEY error (59). */ struct open_struct { unsigned char oname[67], /* file name */ okfname[67]; /* key file name */ int orecl, /* record length */ *okps, /* key posn */ *okln, /* key length */ *okucase, /* key upper case flag */ opageoflow, /* page over flow count */ okw; /* key work size */ short int omode, /* input, output outin */ otype, /* display, internal */ ofiletype, /* seq, relative, keyed */ oshare, /* share status */ ocreate; /* create status */ };