From b70fc2f6394f096ee6c4952a6fa7fd4bd141a270 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Sun, 21 Feb 2016 19:07:54 -0500 Subject: [PATCH] Upgrade to version 1.3 = Hunter Goatley This version was on the VMS FREEWARE disk at some point. It shipped with the included .exes, though modern windows systems certainly don't support the direct access to SCSI DLL that's used. --- extracters/ods2/aareadme.too | 22 + extracters/ods2/aareadme.txt | 175 +++ extracters/ods2/access.c | 1228 +++++++++++---------- extracters/ods2/access.h | 243 +++-- extracters/ods2/build.com | 78 +- extracters/ods2/cache.c | 566 +++++----- extracters/ods2/cache.h | 57 +- extracters/ods2/descrip.h | 46 +- extracters/ods2/descrip.mms | 58 + extracters/ods2/device.c | 85 +- extracters/ods2/direct.c | 772 +++++++++----- extracters/ods2/direct.h | 18 +- extracters/ods2/fibdef.h | 8 +- extracters/ods2/header.h | 189 ++++ extracters/ods2/makefile.nt | 53 + extracters/ods2/makefile.solaris | 36 + extracters/ods2/makefile.tru64 | 34 + extracters/ods2/makefile.unix | 36 + extracters/ods2/memory.h | 3 + extracters/ods2/ods2.c | 406 +++++-- extracters/ods2/ods2.rc | 109 ++ extracters/ods2/ods2_alpha.exe | Bin 0 -> 79872 bytes extracters/ods2/ods2_solaris_intel.exe | Bin 0 -> 276992 bytes extracters/ods2/ods2_solaris_sparc.exe | Bin 0 -> 255488 bytes extracters/ods2/ods2_tru64.exe | Bin 0 -> 217088 bytes extracters/ods2/ods2_vax_decc.exe | Bin 0 -> 44032 bytes extracters/ods2/ods2_vax_vaxc.exe | Bin 0 -> 40448 bytes extracters/ods2/ods2_win32.exe | Bin 0 -> 69632 bytes extracters/ods2/phyio.h | 2 +- extracters/ods2/phynt.c | 707 ++++++++----- extracters/ods2/phyunix.c | 102 ++ extracters/ods2/phyvms.c | 68 +- extracters/ods2/resource.h | 15 + extracters/ods2/rms.c | 546 +++++++--- extracters/ods2/rms.h | 71 +- extracters/ods2/scsidefs.h | 271 +++++ extracters/ods2/ssdef.h | 16 +- extracters/ods2/update.c | 677 ++++++++++++ extracters/ods2/vmstime.c | 1347 +++++++++++++++--------- extracters/ods2/vmstime.h | 174 ++- extracters/ods2/wnaspi32.def | 6 + extracters/ods2/wnaspi32.exp | Bin 0 -> 781 bytes extracters/ods2/wnaspi32.h | 376 +++++++ 43 files changed, 6023 insertions(+), 2577 deletions(-) create mode 100644 extracters/ods2/aareadme.too create mode 100644 extracters/ods2/aareadme.txt create mode 100644 extracters/ods2/descrip.mms create mode 100644 extracters/ods2/header.h create mode 100644 extracters/ods2/makefile.nt create mode 100644 extracters/ods2/makefile.solaris create mode 100644 extracters/ods2/makefile.tru64 create mode 100644 extracters/ods2/makefile.unix create mode 100644 extracters/ods2/memory.h create mode 100644 extracters/ods2/ods2.rc create mode 100644 extracters/ods2/ods2_alpha.exe create mode 100644 extracters/ods2/ods2_solaris_intel.exe create mode 100644 extracters/ods2/ods2_solaris_sparc.exe create mode 100644 extracters/ods2/ods2_tru64.exe create mode 100644 extracters/ods2/ods2_vax_decc.exe create mode 100644 extracters/ods2/ods2_vax_vaxc.exe create mode 100644 extracters/ods2/ods2_win32.exe create mode 100644 extracters/ods2/phyunix.c create mode 100644 extracters/ods2/resource.h create mode 100644 extracters/ods2/scsidefs.h create mode 100644 extracters/ods2/update.c create mode 100644 extracters/ods2/wnaspi32.def create mode 100644 extracters/ods2/wnaspi32.exp create mode 100644 extracters/ods2/wnaspi32.h diff --git a/extracters/ods2/aareadme.too b/extracters/ods2/aareadme.too new file mode 100644 index 0000000..85a76bf --- /dev/null +++ b/extracters/ods2/aareadme.too @@ -0,0 +1,22 @@ +ODS2 V1.3, 26-SEP-2001 + +This release of ODS2 has been made by me, working closely with, and +getting approval from, Paul. + +It will compile cleanly on OpenVMS Alpha, Windows NT/2000 using +Visual C++ V6.0, Tru64 UNIX V5, and Solaris/Sparc using gcc. + +To build on Windows 2000: + + C:> nmake -f makefile.nt + +To build on VMS: + + $ mmk + + +Hunter +------ +Hunter Goatley +goathunter@goatley.com +http://www.goatley.com/hunter/ diff --git a/extracters/ods2/aareadme.txt b/extracters/ods2/aareadme.txt new file mode 100644 index 0000000..4e72db1 --- /dev/null +++ b/extracters/ods2/aareadme.txt @@ -0,0 +1,175 @@ + ODS2 June '98 + + A Program to Read ODS2 Disk Volumes + + +Say, what is this? + ODS2 is a program to read VMS disk volumes written in VMS + ODS2 format. + +Why bother? + Well sometimes it is convenient to see what is on a VMS CD, + or copy files from VMS disk on another platform. Maybe in + future it could be used as a basis for a PC Bookreader + program, or possibly other software? + +What other platforms? + ODS2 is written in 'Standard C' with the intent that it can + be compiled and run on non-VMS systems. However this requires + a C compiler which has 32 bit 'int' types, 16 bit 'short' + types, and 8 bit 'char'. The current version does no special + 'endian' handling so it can only be run on systems which are + little-endian like the VAX. Fortunately that inludes Intel... + +Could it be made to run on big-endian systems? + Yes it could! This would probably best be done by defining + C macros or functions to extract words or long words from the + disk structures as appropriate. On a little-endian system these + would be simply pass-through, while on a big-endian system they + would reverse the byte order. I have not attempted this because + I don't have a suitable test system!! + +What else is needed? + Some operating system support is also required to read an + absolute disk sector from the target disk. This is NOT as + easy as it sounds. I do not currently have sufficient + documentation to set this up for as many platforms as I + would like!! However I do have modules to read disks under + VMS (easy!) and floppies and CD under OS2, Windows 95 and + Windows NT. + +How do I build it? + On a VMS system ODS2 can be compiled by executing the + procedure BUILD.COM. On other platforms you need to compile + Ods2.c, Rms.c, Direct.c, Access.c, Device.c, Cache.c, Vmstime.c, + and the appropriate Phy*.c routine for your system. On OS/2 I + compile using the gcc command:- + gcc -fdollars-in-identifiers ods2.c,rms.c,direct.c, + access.c,device.c,cache.c,phyos2.c,vmstime.c + +What can it do? + Basically ODS2 provides cut down DIRECTORY, COPY and + SEARCH commands for VMS volumes on non-VMS systems. These + can be used to find out what is on a VMS volume, and copy + files onto the local file sytem. + +What file types? + Basically ODS2 can only deal with sequential files. I do not + have information on how indexed file types are constructed, + and relative files are of limited interest. + +What about volume sets? + ODS2 does contain support for multi-volume sets. However there + is no checking that the correct volumes have been specified and + error handling is very fragile. You should ensure that you + specify volume set mount commands very carefully! + +What about ODS5? + Sorry, but I have no idea! I have not seen any ODS5 information + or specifications. Most likely this program will fall in a heap + when presented with an ODS5 disk volume. + +What about bugs? + There are plenty!! This code has been tested for several hours + by a single developer/user on one workstation (absolutely no + testing or input from any other person up to this point!). + Contrast this to the VMS filesystem which has had hundreds of + developers, millions of users, and has run on about 500,000 + systems over the last 20 years!! I would hope to fix some of + the more severe limitations and provide better error handling + fairly soon, perhaps even put some comments into the code? + Maybe the next release might have fewer bugs? + +It is free? + Yeap! It is provided 'as is' to help people in the VMS + community. However there is NO SUPPORT! I will try to fix + any reported problems, but as I really only get to work on + it while the kids are at Scouts on Monday nights, fixes + happen slowly! But if you have comments or suggestions then + please feel free to mail me! + +Can I use the code? + Yeap! You can use and modify the code provided that you + acknowledge the author in the source of any modules which use + any part of this code. I would also appreciate, where possible, + being sent any enhancements for my own use. + +Can I call the routines from my program? + You should be able to. Many of the modules follow an 'RMS' + sort of standard, and programs which only ever read RMS files + from C might be converted to read VMS volumes on another platform + without too much effort. In addition to the RMSish interface, + it would not be difficult to package up an $ASSIGN/$QIOW interface + for common file operations... + +What is the status of ODS2? + This is the first release - actually more like a prototype + than an real release! But it may generate useful feedback and + possibly be useful to others the way it is? However if you are + tempted to use this version for real file transfers, DO YOUR OWN + TESTING first! This program may not have encountered volumes and + files like yours and could easily generate garbage results!!! + +Is more work happening? + Yes! I find the program very useful moving stuff from my + VAXstation to my PC. I would like to be able to write ODS2 volumes + so that I can move files in the other direction! And yes I hope + to generally improve the code - particularly in the area of error + handling! + +Can I make a suggestion? + You sure can! If you see something which needs improvement then + let me know. It may be more interesting than whatever I am doing now! + In fact if I don't hear from anyone then I might even loose interest! + +Can I see a command sample? + Sure:- + C:> ODS2 + ODS2 v1.2 + $> mount E:,F: + %MOUNT-I-MOUNTED, Volume FOX1 mounted on E: + %MOUNT-I-MOUNTED, Volume FOX2 mounted on F: + $> direct/file E:[*...] + Directory E:[PNANKERVIS] + 3MONTH.LOWUSE;1 (51,20,2) + ACCTEST.COM;1 (137,4,1) + ACCTEST.EXE;1 (53,4,2) + ..... + $> set default E:[sys0.sysmgr] + $> dir [-.sys*...].% + ..... + $> copy *.c *.* + %COPY-S-COPIED, E:[SYS0.SYSMGR]ACCESS.C;1 copied to ACCESS.C (3 records) + .... + $> show time + 24-MAR-1998 20:15:23.5 + $> dismount E: + $> exit + +What commands are supported? + A summary is:- + mount DRIVE:[,DRIVE:...] + directory [/file|/size|/date] [FILE-SPEC] + copy FILE-SPEC OUTPUT-FILE + dismount DRIVE: + search FILE-SPEC STRING + set default DIR-SPEC + show default + show time + exit + Note - DRIVE: is normally the native system drive name, + for example D: might be a CD on a PC - xxx: might be + /dev/xxx on a Unix system. + - when a list of drives is specified on the mount command + they are assumed to contain a single valid volume set + (this is not validated!!) + - file-spec is in the usual VMS syntax and may contain + wildcards (for example A:[-.*obj%%...]*abc*.obj;-2) + +Who would write this? + Me! Maybe it will become the basis of something more? If you + have suggestions or want to know more then please mail me at + paulnank@au1.ibm.com + + Thanks for listening! + Paul Nankervis diff --git a/extracters/ods2/access.c b/extracters/ods2/access.c index eac583a..916c556 100644 --- a/extracters/ods2/access.c +++ b/extracters/ods2/access.c @@ -1,4 +1,4 @@ -/* Access.c v1.2 */ +/* Access.c v1.3 */ /* This is part of ODS2 written by Paul Nankervis, @@ -10,15 +10,11 @@ the contibution of the original author. */ -/* This module implements 'accessing' files on an ODS2 +/* + This module implements 'accessing' files on an ODS2 disk volume. It uses its own low level interface to support 'higher level' APIs. For example it is called by the - 'RMS' routines. I also had a module to implement - SYS$ASSIGN, SYS$QIOW, etc which called these routines, - the directory routines, physical I/O etc.... */ - -/* - Oh to have time to make mount do a bit more checking... :-( + 'RMS' routines. */ #include @@ -30,97 +26,116 @@ #include "phyio.h" -#define DEBUGx on +#define DEBUGx +/* checksum() to produce header checksum values... */ - - - -/* checksum: to produce block checksum values... */ - -unsigned short checksum(unsigned short *block) +unsigned short checksum(vmsword *block) { register int count = 255; register unsigned result = 0; register unsigned short *ptr = block; do { - result += *ptr++; + register unsigned data = *ptr++; + result += VMSWORD(data); } while (--count > 0); return result; } +/* rvn_to_dev() find device from relative volume number */ -/* deaccesshead: release header from INDEXF... */ - -unsigned deaccesshead(struct VIOC *vioc,struct HEAD *head,unsigned modmask) +struct VCBDEV *rvn_to_dev(struct VCB *vcb,unsigned rvn) { -#ifdef DEBUG - printf("Deaccessing header %x\n",vioc->cache.keyval); -#endif - if (modmask) head->fh2$w_checksum = checksum((u_word *) head); - return deaccesschunk(vioc,modmask,1); + if (rvn < 2) { + if (vcb->vcbdev[0].dev != NULL) return vcb->vcbdev; + } else { + if (rvn <= vcb->devices) { + if (vcb->vcbdev[rvn - 1].dev != NULL) + return &vcb->vcbdev[rvn - 1]; + } + } + return NULL; /* RVN illegal or device not mounted */ +} + +/* fid_copy() copy fid from file header with default rvn! */ + +void fid_copy(struct fiddef *dst,struct fiddef *src,unsigned rvn) +{ + dst->fid$w_num = VMSWORD(src->fid$w_num); + dst->fid$w_seq = VMSWORD(src->fid$w_seq); + if (src->fid$b_rvn == 0) { + dst->fid$b_rvn = rvn; + } else { + dst->fid$b_rvn = src->fid$b_rvn; + } + dst->fid$b_nmx = src->fid$b_nmx; +} + +/* deaccesshead() release header from INDEXF... */ + +unsigned deaccesshead(struct VIOC *vioc,struct HEAD *head,unsigned idxblk) +{ + if (head && idxblk) { + unsigned short check = checksum((vmsword *) head); + head->fh2$w_checksum = VMSWORD(check); + } + return deaccesschunk(vioc,idxblk,1,1); } -/* accesshead: find file or extension header from INDEXF... */ +/* accesshead() find file or extension header from INDEXF... */ -unsigned accesshead(struct VCB *vcb,struct fiddef *fid, +unsigned accesshead(struct VCB *vcb,struct fiddef *fid,unsigned seg_num, struct VIOC **vioc,struct HEAD **headbuff, - unsigned *modmask,unsigned wrtflg) + unsigned *retidxblk,unsigned wrtflg) { register unsigned sts; register struct VCBDEV *vcbdev; - register unsigned idxblk = fid->fid$w_num + (fid->fid$b_nmx << 16) - 1; - if (fid->fid$b_rvn > vcb->devices) return SS$_NOSUCHFILE; - if (fid->fid$b_rvn < 2) { - vcbdev = vcb->vcbdev; - } else { - vcbdev = &vcb->vcbdev[fid->fid$b_rvn - 1]; - } - if (vcbdev->dev == NULL) return SS$_NOSUCHFILE; + register unsigned idxblk; + vcbdev = rvn_to_dev(vcb,fid->fid$b_rvn); + if (vcbdev == NULL) return SS$_DEVNOTMOUNT; if (wrtflg && ((vcb->status & VCB_WRITE) == 0)) return SS$_WRITLCK; -#ifdef DEBUG - printf("Accessing header (%d,%d,%d)\n",(fid->fid$b_nmx << 16) + - fid->fid$w_num,fid->fid$w_seq,fid->fid$b_rvn); -#endif - idxblk += vcbdev->home.hm2$w_ibmapvbn + vcbdev->home.hm2$w_ibmapsize; - if (idxblk >= swapw(vcbdev->idxfcb->head->fh2$w_recattr.fat$l_efblk)) return SS$_NOSUCHFILE; + idxblk = fid->fid$w_num + (fid->fid$b_nmx << 16) - 1 + + VMSWORD(vcbdev->home.hm2$w_ibmapvbn) + VMSWORD(vcbdev->home.hm2$w_ibmapsize); + if (vcbdev->idxfcb->head != NULL) { + if (idxblk >= VMSSWAP(vcbdev->idxfcb->head->fh2$w_recattr.fat$l_efblk)) { + printf("Not in index file\n"); + return SS$_NOSUCHFILE; + } + } sts = accesschunk(vcbdev->idxfcb,idxblk,vioc,(char **) headbuff, - NULL,wrtflg ? 1 : 0,modmask); + NULL,wrtflg ? 1 : 0); if (sts & 1) { register struct HEAD *head = *headbuff; - if (checksum((u_word *) head) != head->fh2$w_checksum) { -#ifdef DEBUG - printf("Accesshead checksum %d != %d\n",checksum((u_word *) head),head->fh2$w_checksum); -#endif + if (retidxblk) { + if (wrtflg) { + *retidxblk = idxblk; + } else { + *retidxblk = 0; + } + } + if (VMSWORD(head->fh2$w_fid.fid$w_num) != fid->fid$w_num || + head->fh2$w_fid.fid$b_nmx != fid->fid$b_nmx || + VMSWORD(head->fh2$w_fid.fid$w_seq) != fid->fid$w_seq || + (head->fh2$w_fid.fid$b_rvn != fid->fid$b_rvn && + head->fh2$w_fid.fid$b_rvn != 0)) { + /* lib$signal(SS$_NOSUCHFILE); */ sts = SS$_NOSUCHFILE; } else { - if (head->fh2$w_fid.fid$w_num != fid->fid$w_num || - head->fh2$w_fid.fid$b_nmx != fid->fid$b_nmx || - head->fh2$w_fid.fid$w_seq != fid->fid$w_seq || - (head->fh2$w_fid.fid$b_rvn != fid->fid$b_rvn && - head->fh2$w_fid.fid$b_rvn != 0)) { -#ifdef DEBUG - printf("Accesshead fileid doesn't match %d %d %d\n", - fid->fid$w_num,fid->fid$w_seq,fid->fid$b_rvn); -#endif - sts = SS$_NOSUCHFILE; + if (head->fh2$b_idoffset < 38 || + head->fh2$b_idoffset > head->fh2$b_mpoffset || + head->fh2$b_mpoffset > head->fh2$b_acoffset || + head->fh2$b_acoffset > head->fh2$b_rsoffset || + head->fh2$b_map_inuse > head->fh2$b_acoffset - head->fh2$b_mpoffset || + checksum((vmsword *) head) != VMSWORD(head->fh2$w_checksum)) { + sts = SS$_DATACHECK; } else { - if (head->fh2$b_idoffset < 38 || - head->fh2$b_idoffset > head->fh2$b_mpoffset || - head->fh2$b_mpoffset > head->fh2$b_acoffset || - head->fh2$b_acoffset > head->fh2$b_rsoffset || - head->fh2$b_map_inuse > (head->fh2$b_acoffset - head->fh2$b_mpoffset)) { -#ifdef DEBUG - printf("Accesshead areas incorrect\n"); -#endif - sts = SS$_NOSUCHFILE; - } + if (VMSWORD(head->fh2$w_seg_num) != seg_num) sts = SS$_FILESEQCHK; } } - if ((sts & 1) == 0) deaccesschunk(*vioc,0,0); + if ((sts & 1) == 0) deaccesschunk(*vioc,0,0,0); } return sts; } @@ -129,153 +144,427 @@ unsigned accesshead(struct VCB *vcb,struct fiddef *fid, +struct WCBKEY { + unsigned vbn; + struct FCB *fcb; + struct WCB *prevwcb; +}; /* WCBKEY passes info to compare/create routines... */ -unsigned getwindow(struct FCB *fcb,unsigned vbn,unsigned *phyrvn,unsigned *phyblk,unsigned *phylen); +/* wcb_compare() compare two windows routine - return -1 for less, 0 for match... */ +/* as a by product keep highest previous entry so that if a new window + is required we don't have to go right back to the initial file header */ -/* This routine has bugs and does NOT work properly yet!!!! - It may be something simple but I haven't had time to look... - So DON'T use mount/write!!! */ - -unsigned deallocfile(struct FCB *fcb) +int wcb_compare(unsigned hashval,void *keyval,void *thiswcb) { - register unsigned sts = 1; - /* - First mark all file clusters as free in BITMAP.SYS - */ - register unsigned vbn = 1; - while (vbn <= fcb->hiblock) { - register unsigned sts; - unsigned rvn,mapblk,maplen; - register struct VCBDEV *vcbdev; - sts = getwindow(fcb,vbn,&rvn,&mapblk,&maplen); - if ((sts & 1) == 0) break; - if (rvn > fcb->vcb->devices) break; - if (rvn < 2) { - vcbdev = fcb->vcb->vcbdev; + register struct WCBKEY *wcbkey = (struct WCBKEY *) keyval; + register struct WCB *wcb = (struct WCB *) thiswcb; + if (wcbkey->vbn < wcb->loblk) { + return -1; /* Search key is less than this window maps... */ + } else { + if (wcbkey->vbn <= wcb->hiblk) { + return 0; /* Search key must be in this window... */ } else { - vcbdev = &fcb->vcb->vcbdev[rvn - 1]; + if (wcbkey->prevwcb == NULL) { + wcbkey->prevwcb = wcb; + } else { + if (wcb->loblk != 0 && wcb->hiblk > wcbkey->prevwcb->hiblk) wcbkey->prevwcb = wcb; + } + return 1; /* Search key is higher than this window... */ } - if (vcbdev->dev == NULL) { - break; + } +} + +/* premap_indexf() called to physically read the header for indexf.sys + so that indexf.sys can be mapped and read into virtual cache.. */ + +struct HEAD *premap_indexf(struct FCB *fcb,unsigned *retsts) +{ + struct HEAD *head; + struct VCBDEV *vcbdev = rvn_to_dev(fcb->vcb,fcb->rvn); + if (vcbdev == NULL) { + *retsts = SS$_DEVNOTMOUNT; + return NULL; + } + head = (struct HEAD *) malloc(sizeof(struct HEAD)); + if (head == NULL) { + *retsts = SS$_INSFMEM; + } else { + *retsts = phyio_read(vcbdev->dev->handle,VMSLONG(vcbdev->home.hm2$l_ibmaplbn) + + VMSWORD(vcbdev->home.hm2$w_ibmapsize),sizeof(struct HEAD), + (char *) head); + if (!(*retsts & 1)) { + free(head); + head = NULL; } else { - unsigned *bitmap,blkcount,modmask; - struct VIOC *vioc; - register unsigned clustersz = vcbdev->home.hm2$w_cluster; - register unsigned clusterno = mapblk / clustersz; - sts = accesschunk(vcbdev->mapfcb,clusterno / 4096 + 2, - &vioc,(char **) &bitmap,&blkcount,1,&modmask); - if (sts & 1) { - register unsigned wordno = (clusterno % 4096) / (sizeof(unsigned) * 8); - register unsigned bitno = clusterno % (sizeof(unsigned) * 8); - do { - register unsigned mask = 1 << bitno; - vbn += clustersz; - maplen -= clustersz; - while (maplen > 0 && ++bitno < (sizeof(unsigned) * 8)) { - mask |= (mask << 1); - vbn += clustersz; - maplen -= clustersz; - } - bitmap[wordno++] |= mask; - bitno = 0; - } while (maplen > 0 && wordno < blkcount / (sizeof(unsigned) * 8)); - sts = deaccesschunk(vioc,modmask,1); + if (VMSWORD(head->fh2$w_fid.fid$w_num) != 1 || + head->fh2$w_fid.fid$b_nmx != 0 || + VMSWORD(head->fh2$w_fid.fid$w_seq) != 1 || + VMSWORD(head->fh2$w_checksum) != checksum((unsigned short *) head)) { + *retsts = SS$_DATACHECK; + free(head); + head = NULL; } } } - /* - Now reset file header bit map in INDEXF.SYS and - update each of the file headers... - */ - { - unsigned rvn = fcb->rvn; - unsigned modmask = fcb->modmask; - struct HEAD *head = fcb->head; - struct VIOC *headvioc = fcb->headvioc; - do { - struct fiddef extfid; - register struct VCBDEV *vcbdev; - if (rvn > fcb->vcb->devices) break; - if (rvn < 2) { - vcbdev = fcb->vcb->vcbdev; - } else { - vcbdev = &fcb->vcb->vcbdev[rvn - 1]; + return head; +} + +/* wcb_create() creates a window control block by reading appropriate + file headers... */ + +void *wcb_create(unsigned hashval,void *keyval,unsigned *retsts) +{ + register struct WCB *wcb = (struct WCB *) malloc(sizeof(struct WCB)); + if (wcb == NULL) { + *retsts = SS$_INSFMEM; + } else { + unsigned curvbn; + unsigned extents = 0; + struct HEAD *head; + struct VIOC *vioc = NULL; + register struct WCBKEY *wcbkey = (struct WCBKEY *) keyval; + wcb->cache.objmanager = NULL; + wcb->cache.objtype = 3; + if (wcbkey->prevwcb == NULL) { + curvbn = wcb->loblk = 1; + wcb->hd_seg_num = 0; + head = wcbkey->fcb->head; + if (head == NULL) { + head = premap_indexf(wcbkey->fcb,retsts); + if (head == NULL) return NULL; + head->fh2$w_ext_fid.fid$w_num = 0; + head->fh2$w_ext_fid.fid$b_nmx = 0; } - if (vcbdev->dev == NULL) { - break; - } else { - unsigned *bitmap,viocmask; - struct VIOC *vioc; - register unsigned fileno = (head->fh2$w_fid.fid$b_nmx << 16) + - head->fh2$w_fid.fid$w_num - 1; - register unsigned idxblk = fileno / 4096 + - vcbdev->home.hm2$w_cluster * 4 + 1; - sts = accesschunk(vcbdev->idxfcb,idxblk,&vioc, - (char **) &bitmap,NULL,1,&viocmask); - if (sts & 1) { - bitmap[(fileno % 4096) / (sizeof(unsigned) * 8)] &= - ~(1 << (fileno % (sizeof(unsigned) * 8))); - sts = deaccesschunk(vioc,viocmask,1); - } else { - break; + fid_copy(&wcb->hd_fid,&head->fh2$w_fid,wcbkey->fcb->rvn); + } else { + wcb->loblk = wcbkey->prevwcb->hiblk + 1; + curvbn = wcbkey->prevwcb->hd_basevbn; + wcb->hd_seg_num = wcbkey->prevwcb->hd_seg_num; + memcpy(&wcb->hd_fid,&wcbkey->prevwcb->hd_fid,sizeof(struct fiddef)); + } + do { + register unsigned short *mp; + register unsigned short *me; + wcb->hd_basevbn = curvbn; + if (wcb->hd_seg_num != 0) { + *retsts = accesshead(wcbkey->fcb->vcb,&wcb->hd_fid,wcb->hd_seg_num,&vioc,&head,NULL,0); + if ((*retsts & 1) == 0) { + free(wcb); + return NULL; } } - head->fh2$w_fid.fid$w_num = 0; - head->fh2$w_fid.fid$b_rvn = 0; - head->fh2$w_fid.fid$b_nmx = 0; - head->fh2$w_checksum = 0; - memcpy(&extfid,&fcb->head->fh2$w_ext_fid,sizeof(struct fiddef)); - sts = deaccesshead(headvioc,head,modmask); - if ((sts & 1) == 0) break; - if (extfid.fid$b_rvn == 0) { - extfid.fid$b_rvn = rvn; - } else { - rvn = extfid.fid$b_rvn; + mp = (unsigned short *) head + head->fh2$b_mpoffset; + me = mp + head->fh2$b_map_inuse; + while (mp < me) { + register unsigned phylen,phyblk; + switch (VMSWORD(*mp) >> 14) { + case 0: + phylen = 0; + mp++; + break; + case 1: + phylen = (VMSWORD(*mp) & 0377) + 1; + phyblk = ((VMSWORD(*mp) & 037400) << 8) | VMSWORD(mp[1]); + mp += 2; + break; + case 2: + phylen = (VMSWORD(*mp) & 037777) + 1; + phyblk = (VMSWORD(mp[2]) << 16) | VMSWORD(mp[1]); + mp += 3; + break; + case 3: + phylen = ((VMSWORD(*mp) & 037777) << 16) + VMSWORD(mp[1]) + 1; + phyblk = (VMSWORD(mp[3]) << 16) | VMSWORD(mp[2]); + mp += 4; + } + curvbn += phylen; + if (phylen != 0 && curvbn > wcb->loblk) { + wcb->phylen[extents] = phylen; + wcb->phyblk[extents] = phyblk; + wcb->rvn[extents] = wcb->hd_fid.fid$b_rvn; + if (++extents >= EXTMAX) { + if (curvbn > wcbkey->vbn) { + break; + } else { + extents = 0; + wcb->loblk = curvbn; + } + } + } } - if (extfid.fid$w_num != 0 || extfid.fid$b_nmx != 0) { - sts = accesshead(fcb->vcb,&extfid,&headvioc,&head,&modmask,1); - if ((sts & 1) == 0) break; - } else { + if (extents >= EXTMAX || (VMSWORD(head->fh2$w_ext_fid.fid$w_num) == 0 + && head->fh2$w_ext_fid.fid$b_nmx == 0)) { break; + } else { + register unsigned rvn; + wcb->hd_seg_num++; + rvn = wcb->hd_fid.fid$b_rvn; + fid_copy(&wcb->hd_fid,&head->fh2$w_ext_fid,rvn); + if (vioc != NULL) deaccesshead(vioc,NULL,0); } } while (1); - if (sts & 1) { - fcb->headvioc = NULL; - cacheuntouch(&fcb->cache,0,1); - cachedelete(&fcb->cache); + if (vioc != NULL) { + deaccesshead(vioc,NULL,0); + } else { + if (wcbkey->fcb->head == NULL) free(head); + } + wcb->hiblk = curvbn - 1; + wcb->extcount = extents; + *retsts = SS$_NORMAL; + if (curvbn <= wcbkey->vbn) { + free(wcb); + *retsts = SS$_DATACHECK; + wcb = NULL; } } - return sts; + return wcb; +} + + +/* getwindow() find a window to map VBN to LBN ... */ + +unsigned getwindow(struct FCB * fcb,unsigned vbn,struct VCBDEV **devptr, + unsigned *phyblk,unsigned *phylen,struct fiddef *hdrfid, + unsigned *hdrseq) +{ + unsigned sts; + struct WCB *wcb; + struct WCBKEY wcbkey; +#ifdef DEBUG + printf("Accessing window for vbn %d, file (%x)\n",vbn,fcb->cache.hashval); +#endif + wcbkey.vbn = vbn; + wcbkey.fcb = fcb; + wcbkey.prevwcb = NULL; + wcb = cache_find((void *) &fcb->wcb,0,&wcbkey,&sts,wcb_compare,wcb_create); + if (wcb == NULL) return sts; + { + register unsigned extent = 0; + register unsigned togo = vbn - wcb->loblk; + while (togo >= wcb->phylen[extent]) { + togo -= wcb->phylen[extent]; + if (++extent > wcb->extcount) return SS$_BUGCHECK; + } + *devptr = rvn_to_dev(fcb->vcb,wcb->rvn[extent]); + *phyblk = wcb->phyblk[extent] + togo; + *phylen = wcb->phylen[extent] - togo; + if (hdrfid != NULL) memcpy(hdrfid,&wcb->hd_fid,sizeof(struct fiddef)); + if (hdrseq != NULL) *hdrseq = wcb->hd_seg_num; +#ifdef DEBUG + printf("Mapping vbn %d to %d (%d -> %d)[%d] file (%x)\n", + vbn,*phyblk,wcb->loblk,wcb->hiblk,wcb->hd_basevbn,fcb->cache.hashval); +#endif + cache_untouch(&wcb->cache,1); + } + if (*devptr == NULL) return SS$_DEVNOTMOUNT; + return SS$_NORMAL; +} + + +/* Object manager for VIOC objects:- if the object has been + modified then we need to flush it to disk before we let + the cache routines do anything to it... */ + +void *vioc_manager(struct CACHE * cacheobj,int flushonly) +{ + register struct VIOC *vioc = (struct VIOC *) cacheobj; + if (vioc->modmask != 0) { + register struct FCB *fcb = vioc->fcb; + register int length = VIOC_CHUNKSIZE; + register unsigned curvbn = vioc->cache.hashval + 1; + register char *address = (char *) vioc->data; + register unsigned modmask = vioc->modmask; + printf("\nvioc_manager writing vbn %d\n",curvbn); + do { + register unsigned sts; + int wrtlen = 0; + unsigned phyblk,phylen; + struct VCBDEV *vcbdev; + while (length > 0 && (1 & modmask) == 0) { + length--; + curvbn++; + address += 512; + modmask = modmask >> 1; + } + while (wrtlen < length && (1 & modmask) != 0) { + wrtlen++; + modmask = modmask >> 1; + } + length -= wrtlen; + while (wrtlen > 0) { + if (fcb->highwater != 0 && curvbn >= fcb->highwater) { + length = 0; + break; + } + sts = getwindow(fcb,curvbn,&vcbdev,&phyblk,&phylen,NULL,NULL); + if (!(sts & 1)) return NULL; + if (phylen > wrtlen) phylen = wrtlen; + if (fcb->highwater != 0 && curvbn + phylen > fcb->highwater) { + phylen = fcb->highwater - curvbn; + } + sts = phyio_write(vcbdev->dev->handle,phyblk,phylen * 512,address); + if (!(sts & 1)) return NULL; + wrtlen -= phylen; + curvbn += phylen; + address += phylen * 512; + } + } while (length > 0 && modmask != 0); + vioc->modmask = 0; + vioc->cache.objmanager = NULL; + } + return cacheobj; +} + + +/* deaccesschunk() to deaccess a VIOC (chunk of a file) */ + +unsigned deaccesschunk(struct VIOC *vioc,unsigned wrtvbn, + int wrtblks,int reuse) +{ +#ifdef DEBUG + printf("Deaccess chunk %8x\n",vioc->cache.hashval); +#endif + if (wrtvbn) { + register unsigned modmask; + if (wrtvbn <= vioc->cache.hashval || + wrtvbn + wrtblks > vioc->cache.hashval + VIOC_CHUNKSIZE + 1) { + return SS$_BADPARAM; + } + modmask = 1 << (wrtvbn - vioc->cache.hashval - 1); + while (--wrtblks > 0) modmask |= modmask << 1; + if ((vioc->wrtmask | modmask) != vioc->wrtmask) return SS$_WRITLCK; + vioc->modmask |= modmask; + if (vioc->cache.refcount == 1) vioc->wrtmask = 0; + vioc->cache.objmanager = vioc_manager; + } + cache_untouch(&vioc->cache,reuse); + return SS$_NORMAL; +} + + +void *vioc_create(unsigned hashval,void *keyval,unsigned *retsts) +{ + register struct VIOC *vioc = (struct VIOC *) malloc(sizeof(struct VIOC)); + if (vioc == NULL) { + *retsts = SS$_INSFMEM; + } else { + register int length; + register unsigned curvbn = hashval + 1; + register char *address; + register struct FCB *fcb = (struct FCB *) keyval; + vioc->cache.objmanager = NULL; + vioc->cache.objtype = 7; + vioc->fcb = fcb; + vioc->wrtmask = 0; + vioc->modmask = 0; + length = fcb->hiblock - curvbn + 1; + if (length > VIOC_CHUNKSIZE) length = VIOC_CHUNKSIZE; + address = (char *) vioc->data; + do { + if (fcb->highwater != 0 && curvbn >= fcb->highwater) { + memset(address,0,length * 512); + break; + } else { + register unsigned sts; + unsigned phyblk,phylen; + struct VCBDEV *vcbdev; + sts = getwindow(fcb,curvbn,&vcbdev,&phyblk,&phylen,NULL,NULL); + if (sts & 1) { + if (phylen > length) phylen = length; + if (fcb->highwater != 0 && curvbn + phylen > fcb->highwater) { + phylen = fcb->highwater - curvbn; + } + sts = phyio_read(vcbdev->dev->handle,phyblk,phylen * 512,address); + } + if ((sts & 1) == 0) { + free(vioc); + *retsts = sts; + return NULL; + } + length -= phylen; + curvbn += phylen; + address += phylen * 512; + } + } while (length > 0); + *retsts = SS$_NORMAL; + } + return vioc; } -/* deaccessfile: finish accessing a file.... */ +/* accesschunk() return pointer to a 'chunk' of a file ... */ + +unsigned accesschunk(struct FCB *fcb,unsigned vbn,struct VIOC **retvioc, + char **retbuff,unsigned *retblocks,unsigned wrtblks) +{ + unsigned sts; + register int blocks; + register struct VIOC *vioc; +#ifdef DEBUG + printf("Access chunk %8x %d (%x)\n",base,vbn,fcb->cache.hashval); +#endif + if (vbn < 1 || vbn > fcb->hiblock) return SS$_ENDOFFILE; + blocks = (vbn - 1) / VIOC_CHUNKSIZE * VIOC_CHUNKSIZE; + if (wrtblks) { + if ((fcb->status & FCB_WRITE) == 0) return SS$_WRITLCK; + if (vbn + wrtblks > blocks + VIOC_CHUNKSIZE + 1) { + return SS$_BADPARAM; + } + } + vioc = cache_find((void *) &fcb->vioc,blocks,fcb,&sts,NULL,vioc_create); + if (vioc == NULL) return sts; + /* + Return result to caller... + */ + *retvioc = vioc; + blocks = vbn - blocks - 1; + *retbuff = vioc->data[blocks]; + if (wrtblks || retblocks != NULL) { + register unsigned modmask = 1 << blocks; + blocks = VIOC_CHUNKSIZE - blocks; + if (vbn + blocks > fcb->hiblock) blocks = fcb->hiblock - vbn + 1; + if (wrtblks && blocks > wrtblks) blocks = wrtblks; + if (retblocks != NULL) *retblocks = blocks; + if (wrtblks && blocks) { + while (--blocks > 0) modmask |= modmask << 1; + vioc->wrtmask |= modmask; + vioc->cache.objmanager = vioc_manager; + } + } + return SS$_NORMAL; +} + + +unsigned deallocfile(struct FCB *fcb); + +/* deaccessfile() finish accessing a file.... */ unsigned deaccessfile(struct FCB *fcb) { #ifdef DEBUG - printf("Deaccessing file (%x) reference %d\n",fcb->cache.keyval,fcb->cache.refcount); + printf("Deaccessing file (%x) reference %d\n",fcb->cache.hashval,fcb->cache.refcount); #endif if (fcb->cache.refcount == 1) { register unsigned refcount; - refcount = cacherefcount((struct CACHE *) fcb->wcb) + - cacherefcount((struct CACHE *) fcb->vioc); + refcount = cache_refcount((struct CACHE *) fcb->wcb) + + cache_refcount((struct CACHE *) fcb->vioc); if (refcount != 0) { - printf("File reference counts non-zero %d\n",refcount); + printf("File reference counts non-zero %d (%d)\n",refcount, + fcb->cache.hashval); #ifdef DEBUG printf("File reference counts non-zero %d %d\n", - cacherefcount((struct CACHE *) fcb->wcb),cacherefcount((struct CACHE *) fcb->vioc)); + cache_refcount((struct CACHE *) fcb->wcb),cache_refcount((struct CACHE *) fcb->vioc)); #endif return SS$_BUGCHECK; } - if (fcb->cache.status & CACHE_WRITE) { - if (fcb->head->fh2$l_filechar & FH2$M_MARKDEL) { + if (fcb->status & FCB_WRITE) { + if (VMSLONG(fcb->head->fh2$l_filechar) & FH2$M_MARKDEL) { return deallocfile(fcb); } } } - cacheuntouch(&fcb->cache,1,fcb->cache.status & CACHE_WRITE); + cache_untouch(&fcb->cache,1); return SS$_NORMAL; } @@ -285,137 +574,105 @@ unsigned deaccessfile(struct FCB *fcb) cache routines get us! But we when run out of excuses it is time to clean up the file header... :-( */ -struct CACHE *fcbmanager(struct CACHE *cacheobj) +void *fcb_manager(struct CACHE *cacheobj,int flushonly) { register struct FCB *fcb = (struct FCB *) cacheobj; - if (fcb->cache.refcount == 0) { - if (fcb->vioc != NULL) { - if (fcb->vioc->cache.refcount == 0) { - cacheobj = &fcb->vioc->cache; - } else { - cacheobj = NULL; - } - } else { - if (fcb->wcb != NULL) { - if (fcb->wcb->cache.refcount == 0) { - cacheobj = &fcb->wcb->cache; - } else { - cacheobj = NULL; - } - } else { -#ifdef DEBUG - printf("Cleaning up file (%x)\n",fcb->cache.keyval); -#endif - if (fcb->headvioc != NULL) { -#ifdef DEBUG - printf("File header deaccess (%x) %x\n",fcb->cache.keyval,fcb->cache.status); -#endif - deaccesshead(fcb->headvioc,fcb->head,fcb->modmask); - fcb->headvioc = NULL; - } - } - } - } else { - cacheobj = NULL; + if (fcb->vioc != NULL) return &fcb->vioc->cache; + if (fcb->wcb != NULL) return &fcb->wcb->cache; + if (fcb->cache.refcount != 0 || flushonly) return NULL; + if (fcb->headvioc != NULL) { + deaccesshead(fcb->headvioc,fcb->head,fcb->headvbn); + fcb->headvioc = NULL; } return cacheobj; } +void *fcb_create(unsigned filenum,void *keyval,unsigned *retsts) +{ + register struct FCB *fcb = (struct FCB *) malloc(sizeof(struct FCB)); + if (fcb == NULL) { + *retsts = SS$_INSFMEM; + } else { + fcb->cache.objmanager = fcb_manager; + fcb->cache.objtype = 2; + fcb->vcb = NULL; + fcb->headvioc = NULL; + fcb->head = NULL; + fcb->wcb = NULL; + fcb->vioc = NULL; + fcb->headvbn = 0; + fcb->hiblock = 100000; + fcb->highwater = 0; + fcb->status = 0; + fcb->rvn = 0; + } + return fcb; +} -/* accessfile: open up file for access... */ + +/* accessfile() open up file for access... */ unsigned accessfile(struct VCB * vcb,struct fiddef * fid,struct FCB **fcbadd, unsigned wrtflg) { + unsigned sts; register struct FCB *fcb; - unsigned create = sizeof(struct FCB); - register unsigned fileno = (fid->fid$b_nmx << 16) + fid->fid$w_num; + register unsigned filenum = (fid->fid$b_nmx << 16) + fid->fid$w_num; #ifdef DEBUG printf("Accessing file (%d,%d,%d)\n",(fid->fid$b_nmx << 16) + fid->fid$w_num,fid->fid$w_seq,fid->fid$b_rvn); #endif - if (fileno < 1) return SS$_BADPARAM; + if (filenum < 1) return SS$_BADPARAM; if (wrtflg && ((vcb->status & VCB_WRITE) == 0)) return SS$_WRITLCK; - if (fid->fid$b_rvn > 1) fileno |= ((fid->fid$b_rvn - 1) << 24); - fcb = cachesearch((void *) &vcb->fcb,fileno,0,NULL,NULL,&create); - if (fcb == NULL) return SS$_INSFMEM; + if (fid->fid$b_rvn > 1) filenum |= fid->fid$b_rvn << 24; + fcb = cache_find((void *) &vcb->fcb,filenum,NULL,&sts,NULL,fcb_create); + if (fcb == NULL) return sts; /* If not found make one... */ - if (create == 0) { - fcb->cache.status |= 0x100; /* For debugging! */ + *fcbadd = fcb; + if (fcb->vcb == NULL) { fcb->rvn = fid->fid$b_rvn; if (fcb->rvn == 0 && vcb->devices > 1) fcb->rvn = 1; fcb->vcb = vcb; - fcb->wcb = NULL; - fcb->headvioc = NULL; - fcb->vioc = NULL; - fcb->cache.objmanager = fcbmanager; } if (wrtflg) { - if (fcb->headvioc != NULL && (fcb->cache.status & CACHE_WRITE) == 0) { + if (fcb->headvioc != NULL && (fcb->status & FCB_WRITE) == 0) { deaccesshead(fcb->headvioc,NULL,0); fcb->headvioc = NULL; } - fcb->cache.status |= CACHE_WRITE; + fcb->status |= FCB_WRITE; } if (fcb->headvioc == NULL) { register unsigned sts; - if (vcb->idxboot != NULL) { - *fcbadd = fcb; - fcb->hiblock = 32767; /* guess at indexf.sys file size */ - fcb->highwater = 0; - fcb->head = vcb->idxboot; /* Load bootup header */ - } - sts = accesshead(vcb,fid,&fcb->headvioc,&fcb->head,&fcb->modmask,wrtflg); + sts = accesshead(vcb,fid,0,&fcb->headvioc,&fcb->head,&fcb->headvbn,wrtflg); if (sts & 1) { - fcb->hiblock = swapw(fcb->head->fh2$w_recattr.fat$l_hiblk); + fcb->hiblock = VMSSWAP(fcb->head->fh2$w_recattr.fat$l_hiblk); if (fcb->head->fh2$b_idoffset > 39) { - fcb->highwater = fcb->head->fh2$l_highwater; + fcb->highwater = VMSLONG(fcb->head->fh2$l_highwater); } else { fcb->highwater = 0; } } else { + printf("Accessfile status %d\n",sts); fcb->cache.objmanager = NULL; - cacheuntouch(&fcb->cache,0,0); - cachefree(&fcb->cache); + cache_untouch(&fcb->cache,0); + cache_delete(&fcb->cache); return sts; } } - *fcbadd = fcb; return SS$_NORMAL; } -/* accesserase: delete a file... */ - -unsigned accesserase(struct VCB * vcb,struct fiddef * fid) -{ - struct FCB *fcb; - register int sts; - sts = accessfile(vcb,fid,&fcb,1); - if (sts & 1) { - if (fcb->cache.refcount == 1) { - fcb->head->fh2$l_filechar |= FH2$M_MARKDEL; - sts = deaccessfile(fcb); - } else { - sts = deaccessfile(fcb); - sts = SS$_FILELOCKED; - } - } - return sts; -} - - - -/* dismount: finish processing on a volume */ +/* dismount() finish processing on a volume */ unsigned dismount(struct VCB * vcb) { register unsigned sts,device; struct VCBDEV *vcbdev; int expectfiles = vcb->devices; - int openfiles = cacherefcount(&vcb->fcb->cache); + int openfiles = cache_refcount(&vcb->fcb->cache); if (vcb->status & VCB_WRITE) expectfiles *= 2; #ifdef DEBUG printf("Dismounting disk %d\n",openfiles); @@ -427,33 +684,37 @@ unsigned dismount(struct VCB * vcb) vcbdev = vcb->vcbdev; for (device = 0; device < vcb->devices; device++) { if (vcbdev->dev != NULL) { - if (vcb->status & VCB_WRITE) { + if (vcb->status & VCB_WRITE && vcbdev->mapfcb != NULL) { sts = deaccessfile(vcbdev->mapfcb); - vcbdev->idxfcb->headvioc->cache.status |= CACHE_MODIFIED; - vcbdev->idxfcb->cache.status &= ~CACHE_WRITE; - cacheflush(); + if (!(sts & 1)) break; + vcbdev->idxfcb->status &= ~FCB_WRITE; + vcbdev->mapfcb = NULL; } - cachedeltree(&vcb->fcb->cache); - sts = deaccesshead(vcbdev->idxfcb->headvioc,NULL,0); + cache_remove(&vcb->fcb->cache); + sts = deaccesshead(vcbdev->idxfcb->headvioc,vcbdev->idxfcb->head,vcbdev->idxfcb->headvbn); + if (!(sts & 1)) break; vcbdev->idxfcb->headvioc = NULL; - sts = cacheuntouch(&vcbdev->idxfcb->cache,0,0); - cachedeltree(&vcb->fcb->cache); + cache_untouch(&vcbdev->idxfcb->cache,0); + vcbdev->dev->vcb = NULL; } vcbdev++; } - while (vcb->dircache) cachedelete((struct CACHE *) vcb->dircache); + if (sts & 1) { + cache_remove(&vcb->fcb->cache); + while (vcb->dircache) cache_delete((struct CACHE *) vcb->dircache); #ifdef DEBUG - printf("Post close\n"); - cachedump(); + printf("Post close\n"); + cachedump(); #endif - free(vcb); + free(vcb); + } } return sts; } +#define HOME_LIMIT 100 - -/* mount: make disk volume available for processing... */ +/* mount() make disk volume available for processing... */ unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],struct VCB **retvcb) { @@ -472,391 +733,76 @@ unsigned mount(unsigned flags,unsigned devices,char *devnam[],char *label[],stru sts = SS$_NOSUCHVOL; vcbdev->dev = NULL; if (strlen(devnam[device])) { + int hba; sts = device_lookup(strlen(devnam[device]),devnam[device],1,&vcbdev->dev); + if (!(sts & 1)) break; + for (hba = 1; hba <= HOME_LIMIT; hba++) { + sts = phyio_read(vcbdev->dev->handle,hba,sizeof(struct HOME),(char *) &vcbdev->home); + if (!(sts & 1)) break; + if (hba == VMSLONG(vcbdev->home.hm2$l_homelbn) && + memcmp(vcbdev->home.hm2$t_format,"DECFILE11B ",12) == 0) break; + sts = SS$_DATACHECK; + } if (sts & 1) { - int hba = 1; /* Header block address... */ - do { - if ((sts = phyio_read(vcbdev->dev->handle,hba,sizeof(struct HOME),(char *) &vcbdev->home)) & 1) { - if (memcmp(vcbdev->home.hm2$t_format,"DECFILE11B ",12) != 0) sts = SS$_BADPARAM; + if (VMSWORD(vcbdev->home.hm2$w_checksum2) != checksum((unsigned short *) &vcbdev->home)) { + sts = SS$_DATACHECK; + } else { + if (VMSWORD(vcbdev->home.hm2$w_rvn) != device + 1) + if (VMSWORD(vcbdev->home.hm2$w_rvn) > 1 || device != 0) + sts = SS$_UNSUPVOLSET; + if (vcbdev->dev->vcb != NULL) { + sts = SS$_DEVMOUNT; } - } while ((sts & 1) == 0 && (hba += 1) < 100); - if (sts & 1) { - if (vcbdev->home.hm2$w_checksum2 != checksum((unsigned short *) &vcbdev->home)) { - sts = SS$_DATACHECK; - } else { - struct HEAD idxboot; /* Local for bootstrapping volume */ - struct fiddef idxfid = {1,1,0,0}; - idxfid.fid$b_rvn = device + 1; - if ((sts = phyio_read(vcbdev->dev->handle,vcbdev->home.hm2$l_ibmaplbn + - vcbdev->home.hm2$w_ibmapsize,sizeof(struct HEAD),(char *) &idxboot)) & 1) { - if (idxboot.fh2$w_fid.fid$w_num != idxfid.fid$w_num || - idxboot.fh2$w_fid.fid$b_nmx != idxfid.fid$b_nmx || - idxboot.fh2$w_fid.fid$w_seq != idxfid.fid$w_seq || - (idxboot.fh2$w_fid.fid$b_rvn != 0 && - idxboot.fh2$w_fid.fid$b_rvn != idxfid.fid$b_rvn)) - sts = SS$_DATACHECK; - if (idxboot.fh2$w_checksum != checksum((unsigned short *) &idxboot)) sts = SS$_DATACHECK; - } - vcbdev->idxfcb = NULL; + } + } + if (!(sts & 1)) break; + } + vcbdev++; + } + if (sts & 1) { + vcb->devices = devices; + vcbdev = vcb->vcbdev; + for (device = 0; device < devices; device++) { + vcbdev->idxfcb = NULL; + vcbdev->mapfcb = NULL; + vcbdev->clustersize = 0; + vcbdev->max_cluster = 0; + vcbdev->free_clusters = 0; + if (strlen(devnam[device])) { + struct fiddef idxfid = {1,1,0,0}; + idxfid.fid$b_rvn = device + 1; + sts = accessfile(vcb,&idxfid,&vcbdev->idxfcb,flags & 1); + if (!(sts & 1)) { + vcbdev->dev = NULL; + } else { + vcbdev->dev->vcb = vcb; + if (flags & 1) { + struct fiddef mapfid = {2,2,0,0}; + mapfid.fid$b_rvn = device + 1; + sts = accessfile(vcb,&mapfid,&vcbdev->mapfcb,1); if (sts & 1) { - vcb->devices = device + 1; - vcb->idxboot = &idxboot; /* For getwindow to find index file*/ - sts = accessfile(vcb,&idxfid,&vcbdev->idxfcb,flags & 1); - vcbdev->mapfcb = NULL; + struct VIOC *vioc; + struct SCB *scb; + sts = accesschunk(vcbdev->mapfcb,1,&vioc,(char **) &scb,NULL,0); if (sts & 1) { - vcbdev->dev->vcb = vcb; - if (flags & 1) { - struct fiddef mapfid = {2,2,0,0}; - mapfid.fid$b_rvn = device + 1; - sts = accessfile(vcb,&mapfid,&vcbdev->mapfcb,1); + if (scb->scb$w_cluster == vcbdev->home.hm2$w_cluster) { + vcbdev->clustersize = vcbdev->home.hm2$w_cluster; + vcbdev->max_cluster = (scb->scb$l_volsize + scb->scb$w_cluster - 1) / scb->scb$w_cluster; + deaccesschunk(vioc,0,0,0); + sts = update_freecount(vcbdev,&vcbdev->free_clusters); +printf("Freespace is %d\n",vcbdev->free_clusters); } } } } } } - if ((sts & 1) == 0) vcbdev->dev = NULL; + vcbdev++; } - if (device == 0 && vcbdev->dev == NULL) { - free(vcb); - return sts; - } - vcbdev++; + } else { + free(vcb); + vcb = NULL; } - vcb->idxboot = NULL; if (retvcb != NULL) *retvcb = vcb; return sts; } - - -/* wincmp: compare two windows routine - return -1 for less, 0 for match... */ -/* as a by product keep highest previous entry so that if a new window - is required we don't have to go right back to the initial file header */ - -int wincmp(unsigned keylen,void *key,void *node) -{ - register struct WCB *wcb = (struct WCB *) node; - if (keylen < wcb->loblk) { - return -1; - } else { - if (keylen <= wcb->hiblk) { - return 0; - } else { - register struct WCB **prev_wcb = (struct WCB **) key; - if (*prev_wcb == NULL) { - *prev_wcb = wcb; - } else { - if ((*prev_wcb)->hiblk < wcb->hiblk) *prev_wcb = wcb; - } - return 1; - } - } -} - - -/* getwindow: find a window to map VBN to LBN ... */ - -unsigned getwindow(struct FCB * fcb,unsigned vbn,unsigned *phyrvn,unsigned *phyblk,unsigned *phylen) -{ - register struct WCB *wcb; - struct WCB *prev_wcb = NULL; - unsigned create = sizeof(struct WCB); -#ifdef DEBUG - printf("Accessing window for vbn %d, file (%x)\n",vbn,fcb->cache.keyval); -#endif - wcb = cachesearch((void *) &fcb->wcb,0,vbn,&prev_wcb,wincmp,&create); - if (wcb == NULL) return SS$_INSFMEM; - /* If not found make one... */ - if (create == 0) { - register unsigned wd_base,wd_exts; - unsigned prev_hiblk,rvn; - struct VIOC *vioc; - struct HEAD *head; - wcb->cache.status |= 0x200; /* For debugging! */ - vioc = NULL; - wd_base = 1; - rvn = fcb->rvn; - head = fcb->head; - prev_hiblk = 0; - if (prev_wcb != NULL) { - register unsigned sts; - register struct fiddef *fid = &prev_wcb->hd_fid; - register struct fiddef *filefid = &fcb->head->fh2$w_fid; - if (fid->fid$w_num != filefid->fid$w_num || - fid->fid$b_nmx != filefid->fid$b_nmx || - ((fid->fid$b_rvn > 1 || fcb->rvn > 1) && fid->fid$b_rvn != fcb->rvn)) { - wd_base = prev_wcb->hd_base; - rvn = prev_wcb->hd_fid.fid$b_rvn; - sts = accesshead(fcb->vcb,fid,&vioc,&head,NULL,0); - if ((sts & 1) == 0) { - cacheuntouch(&wcb->cache,0,0); - cachefree(&wcb->cache); - return sts; - } - } - prev_hiblk = prev_wcb->hiblk; - } - wcb->hd_base = wd_base; - wd_exts = 0; -#ifdef DEBUG - printf("Making window %d %d\n",wd_base,prev_hiblk); -#endif - do { - register unsigned short *mp = (unsigned short *) head + head->fh2$b_mpoffset; - register unsigned short *me = mp + head->fh2$b_map_inuse; - while (mp < me) { - register unsigned phylen,phyblk; - switch ((*mp) >> 14) { - case 0: - phylen = 0; - mp++; - break; - case 1: - phylen = ((*mp) & 0377) + 1; - phyblk = (((*mp) & 037400) << 8) + mp[1]; - mp += 2; - break; - case 2: - phylen = ((*mp) & 037777) + 1; - phyblk = (mp[2] << 16) + mp[1]; - mp += 3; - break; - case 3: - phylen = (((*mp) & 037777) << 16) + mp[1] + 1; - phyblk = (mp[3] << 16) + mp[2]; - mp += 4; - } - if (phylen > 0 && wd_base > prev_hiblk) { - register struct EXT *ext; - if (wd_exts == 0) wcb->loblk = wd_base; - ext = &wcb->ext[wd_exts++]; - ext->phylen = phylen; - ext->phyblk = phyblk; - wd_base += phylen; - if (wd_exts >= EXTMAX) { - if (wd_base > vbn) { - break; - } else { - wd_exts = 0; - } - } - } else { - wd_base += phylen; - } - } - if (wd_base > vbn) { - break; - } else { - register unsigned sts; - struct fiddef extfid; - memcpy(&extfid,&head->fh2$w_ext_fid,sizeof(struct fiddef)); - if (extfid.fid$b_rvn != 0 && extfid.fid$b_rvn != rvn) { - wd_exts = 0;/* Can't let window extend across devices */ - rvn = extfid.fid$b_rvn; - } else { - extfid.fid$b_rvn = rvn; - } - if (vioc != NULL) deaccesshead(vioc,NULL,0); - sts = accesshead(fcb->vcb,&extfid,&vioc,&head,NULL,0); - if ((sts & 1) == 0) { - cacheuntouch(&wcb->cache,0,0); - cachefree(&wcb->cache); - return sts; - } - wcb->hd_base = wd_base; - } - } while (wd_base <= vbn); - memcpy(&wcb->hd_fid,&head->fh2$w_fid,sizeof(struct fiddef)); - wcb->hd_fid.fid$b_rvn = rvn; - wcb->hiblk = wd_base - 1; - wcb->extcount = wd_exts; - if (vioc != NULL) deaccesshead(vioc,NULL,0); - } { - register struct EXT *ext = wcb->ext; - register unsigned extcnt = wcb->extcount; - register unsigned togo = vbn - wcb->loblk; - while (togo >= ext->phylen) { - togo -= (ext++)->phylen; - if (extcnt-- < 1) return SS$_BUGCHECK; - } - *phyrvn = wcb->hd_fid.fid$b_rvn; - *phyblk = ext->phyblk + togo; - *phylen = ext->phylen - togo; -#ifdef DEBUG - printf("Mapping vbn %d to %d (%d -> %d)[%d] file (%x)\n", - vbn,*phyblk,wcb->loblk,wcb->hiblk,wcb->hd_base,fcb->cache.keyval); -#endif - cacheuntouch(&wcb->cache,1,0); - } - return SS$_NORMAL; -} - - -/* Object manager for VIOC objects:- if the object has been - modified then we need to flush it to disk before we let - the cache routines do anything to it... - This version rewrites the whole chunk - but we really should - just rewrite the blocks modified as indicated by modmask! */ - -struct CACHE *viocmanager(struct CACHE * cacheobj) -{ - register struct VIOC *vioc = (struct VIOC *) cacheobj; - if (vioc->cache.status & CACHE_MODIFIED) { - register int length = VIOC_CHUNKSIZE; - register struct FCB *fcb = vioc->fcb; - register unsigned base = vioc->cache.keyval; - register char *address = (char *) vioc->data; - printf("\nviocmanager writing vbn %d\n",base); - cachetouch(&fcb->cache); - do { - register unsigned sts; - unsigned rvn,mapblk,maplen; - register struct VCBDEV *vcbdev; - if (fcb->highwater > 0 && base >= fcb->highwater) break; - sts = getwindow(fcb,base,&rvn,&mapblk,&maplen); - if (sts & 1) { - if (maplen > (unsigned)length) maplen = length; - if (fcb->highwater > 0 && base + maplen > fcb->highwater) { - maplen = fcb->head->fh2$l_highwater - base; - } - if (rvn > fcb->vcb->devices) { - sts = SS$_NOSUCHFILE; - } else { - if (rvn < 2) { - vcbdev = fcb->vcb->vcbdev; - } else { - vcbdev = &fcb->vcb->vcbdev[rvn - 1]; - } - if (vcbdev->dev == NULL) return NULL; - sts = phyio_write(vcbdev->dev->handle,mapblk,maplen * 512,address); - } - } - if ((sts & 1) == 0) { - return NULL; - } - length -= maplen; - base += maplen; - address += maplen * 512; - } while (length > 0); - cacheuntouch(&fcb->cache,1,0); - cacheobj->status &= ~CACHE_MODIFIED; - } - return cacheobj; -} - - -/* deaccess a VIOC (chunk of a file) */ - -unsigned deaccesschunk(struct VIOC *vioc,unsigned modmask,int reuse) -{ -#ifdef DEBUG - printf("Deaccess chunk %8x\n",vioc->cache.keyval); -#endif - if ((vioc->wrtmask | modmask) == vioc->wrtmask) { - vioc->modmask |= modmask; - if (vioc->cache.refcount == 1) vioc->wrtmask = 0; - return cacheuntouch(&vioc->cache,reuse,modmask); - } else { - return SS$_WRITLCK; - } -} - - - - -/* accesschunk: return pointer to a 'chunk' of a file ... */ - -unsigned accesschunk(struct FCB *fcb,unsigned vbn,struct VIOC **retvioc, - char **retbuff,unsigned *retblocks,unsigned wrtblks, - unsigned *retmodmask) -{ - /* - First find cache entry... - */ - register struct VIOC *vioc; - unsigned create = sizeof(struct VIOC); - register unsigned base = (vbn - 1) / VIOC_CHUNKSIZE * VIOC_CHUNKSIZE + 1; -#ifdef DEBUG - printf("Access chunk %8x %d (%x)\n",base,vbn,fcb->cache.keyval); -#endif - if (wrtblks && ((fcb->cache.status & CACHE_WRITE) == 0)) return SS$_WRITLCK; - if (vbn < 1 || vbn > fcb->hiblock) return SS$_ENDOFFILE; - vioc = cachesearch((void *) &fcb->vioc,base,0,NULL,NULL,&create); - if (vioc == NULL) return SS$_INSFMEM; - /* - If not found make one... - */ - if (create == 0) { - register unsigned length; - register char *address; - register unsigned mapbase = base; - vioc->cache.status |= 0x400; /* For debugging! */ - vioc->fcb = fcb; - vioc->wrtmask = 0; - vioc->modmask = 0; - length = fcb->hiblock - mapbase + 1; - if (length > VIOC_CHUNKSIZE) length = VIOC_CHUNKSIZE; - address = (char *) vioc->data; - do { - if (fcb->highwater > 0 && mapbase >= fcb->highwater) { - memset(address,0,length * 512); - length = 0; - } else { - register unsigned sts; - unsigned rvn,mapblk,maplen; - register struct VCBDEV *vcbdev; - sts = getwindow(fcb,mapbase,&rvn,&mapblk,&maplen); - if (sts & 1) { - if (maplen > length) maplen = length; - if (fcb->highwater > 0 && mapbase + maplen > fcb->highwater) { - maplen = fcb->head->fh2$l_highwater - mapbase; - } - if (rvn > fcb->vcb->devices) { - sts = SS$_NOSUCHFILE; - } else { - if (rvn < 2) { - vcbdev = fcb->vcb->vcbdev; - } else { - vcbdev = &fcb->vcb->vcbdev[rvn - 1]; - } - if (vcbdev->dev == NULL) return SS$_NOSUCHFILE; - sts = phyio_read(vcbdev->dev->handle,mapblk,maplen * 512,address); - } - } - if ((sts & 1) == 0) { - cacheuntouch(&vioc->cache,0,0); - cachefree(&vioc->cache); - return sts; - } - length -= maplen; - mapbase += maplen; - address += maplen * 512; - } - } while (length > 0); - } - if (wrtblks) { - vioc->cache.status |= CACHE_WRITE; - vioc->cache.objmanager = viocmanager; - } - /* - Return result to caller... - */ - *retvioc = vioc; - *retbuff = vioc->data[vbn - base]; - if (wrtblks || retblocks != NULL || retmodmask != NULL) { - register unsigned modmask = 0; - register unsigned blocks = base + VIOC_CHUNKSIZE - vbn; - if (blocks > fcb->hiblock - vbn) blocks = fcb->hiblock - vbn + 1; - if (wrtblks) if (blocks > wrtblks) blocks = wrtblks; - if (retblocks != NULL) *retblocks = blocks; - if (wrtblks) { - modmask = 1 << (vbn - base); - if (blocks > 1) { - while (--blocks > 0) modmask |= modmask << 1; - } - vioc->wrtmask |= modmask; - } - if (retmodmask != NULL) *retmodmask = modmask; - } - return SS$_NORMAL; -} diff --git a/extracters/ods2/access.h b/extracters/ods2/access.h index 64af773..31c2b18 100644 --- a/extracters/ods2/access.h +++ b/extracters/ods2/access.h @@ -1,4 +1,4 @@ -/* Access.h v1.2 Definitions for file access routines */ +/* Access.h v1.3 Definitions for file access routines */ /* This is part of ODS2 written by Paul Nankervis, @@ -10,11 +10,24 @@ the contibution of the original author. */ - +#define NO_DOLLAR #include "cache.h" #include "vmstime.h" -#define swapw(w) ((((unsigned int)(w[0]))<<16) | (unsigned int)(w[1])) +#ifdef BIG_ENDIAN +#define VMSLONG(l) ((l & 0xff) << 24 | (l & 0xff00) << 8 | (l & 0xff0000) >> 8 | l >> 24) +#define VMSWORD(w) ((w & 0xff) << 8 | w >> 8) +#define VMSSWAP(l) ((l & 0xff0000) << 8 | (l & 0xff000000) >> 8 |(l & 0xff) << 8 | (l & 0xff00) >> 8) +#else +#define VMSLONG(l) l +#define VMSWORD(w) w +#define VMSSWAP(l) ((l & 0xffff) << 16 | l >> 16) +#endif + +typedef unsigned char vmsbyte; +typedef unsigned short vmsword; +typedef unsigned int vmsswap; +typedef unsigned int vmslong; #define FH2$M_NOBACKUP 0x2 #define FH2$M_CONTIG 0x80 @@ -22,140 +35,159 @@ #define FH2$M_MARKDEL 0x8000 #define FH2$M_ERASE 0x20000 -typedef unsigned char u_byte; -typedef unsigned short u_word; -typedef unsigned int u_long; - +#ifdef __ALPHA +#pragma member_alignment save +#pragma nomember_alignment +#endif struct UIC { - u_word u_grp; - u_word u_mem; + vmsword uic$w_mem; + vmsword uic$w_grp; }; struct fiddef { - u_word fid$w_num; - u_word fid$w_seq; - u_byte fid$b_rvn; - u_byte fid$b_nmx; + vmsword fid$w_num; + vmsword fid$w_seq; + vmsbyte fid$b_rvn; + vmsbyte fid$b_nmx; }; struct RECATTR { - u_byte fat$b_rtype; - u_byte fat$b_rattrib; - u_word fat$w_rsize; - u_word fat$l_hiblk[2]; - u_word fat$l_efblk[2]; - u_word fat$w_ffbyte; - u_byte fat$b_bktsize; - u_byte fat$b_vfcsize; - u_word fat$w_maxrec; - u_word fat$w_defext; - u_word fat$w_gbc; - u_byte fat$_UU0[8]; - u_word fat$w_versions; + vmsbyte fat$b_rtype; + vmsbyte fat$b_rattrib; + vmsword fat$w_rsize; + vmsswap fat$l_hiblk; + vmsswap fat$l_efblk; + vmsword fat$w_ffbyte; + vmsbyte fat$b_bktsize; + vmsbyte fat$b_vfcsize; + vmsword fat$w_maxrec; + vmsword fat$w_defext; + vmsword fat$w_gbc; + vmsbyte fat$_UU0[8]; + vmsword fat$w_versions; }; struct HOME { - u_long hm2$l_homelbn; - u_long hm2$l_alhomelbn; - u_long hm2$l_altidxlbn; - u_word hm2$w_struclev; - u_word hm2$w_cluster; - u_word hm2$w_homevbn; - u_word hm2$w_alhomevbn; - u_word hm2$w_altidxvbn; - u_word hm2$w_ibmapvbn; - u_long hm2$l_ibmaplbn; - u_long hm2$l_maxfiles; - u_word hm2$w_ibmapsize; - u_word hm2$w_resfiles; - u_word hm2$w_devtype; - u_word hm2$w_rvn; - u_word hm2$w_setcount; - u_word hm2$w_volchar; + vmslong hm2$l_homelbn; + vmslong hm2$l_alhomelbn; + vmslong hm2$l_altidxlbn; + vmsword hm2$w_struclev; + vmsword hm2$w_cluster; + vmsword hm2$w_homevbn; + vmsword hm2$w_alhomevbn; + vmsword hm2$w_altidxvbn; + vmsword hm2$w_ibmapvbn; + vmslong hm2$l_ibmaplbn; + vmslong hm2$l_maxfiles; + vmsword hm2$w_ibmapsize; + vmsword hm2$w_resfiles; + vmsword hm2$w_devtype; + vmsword hm2$w_rvn; + vmsword hm2$w_setcount; + vmsword hm2$w_volchar; struct UIC hm2$w_volowner; - u_long hm2$l_reserved1; - u_word hm2$w_protect; - u_word hm2$w_fileprot; - u_word hm2$w_reserved2; - u_word hm2$w_checksum1; - struct TIME hm2$q_credate; - u_byte hm2$b_window; - u_byte hm2$b_lru_lim; - u_word hm2$w_extend; - struct TIME hm2$q_retainmin; - struct TIME hm2$q_retainmax; - struct TIME hm2$q_revdate; - u_byte hm2$r_min_class[20]; - u_byte hm2$r_max_class[20]; - u_byte hm2$t_reserved3[320]; - u_long hm2$l_serialnum; + vmslong hm2$l_reserved1; + vmsword hm2$w_protect; + vmsword hm2$w_fileprot; + vmsword hm2$w_reserved2; + vmsword hm2$w_checksum1; + VMSTIME hm2$q_credate; + vmsbyte hm2$b_window; + vmsbyte hm2$b_lru_lim; + vmsword hm2$w_extend; + VMSTIME hm2$q_retainmin; + VMSTIME hm2$q_retainmax; + VMSTIME hm2$q_revdate; + vmsbyte hm2$r_min_class[20]; + vmsbyte hm2$r_max_class[20]; + vmsbyte hm2$t_reserved3[320]; + vmslong hm2$l_serialnum; char hm2$t_strucname[12]; char hm2$t_volname[12]; char hm2$t_ownername[12]; char hm2$t_format[12]; - u_word hm2$w_reserved4; - u_word hm2$w_checksum2; + vmsword hm2$w_reserved4; + vmsword hm2$w_checksum2; }; struct IDENT { char fi2$t_filename[20]; - u_word fi2$w_revision; - struct TIME fi2$q_credate; - struct TIME fi2$q_revdate; - struct TIME fi2$q_expdate; - struct TIME fi2$q_bakdate; + vmsword fi2$w_revision; + VMSTIME fi2$q_credate; + VMSTIME fi2$q_revdate; + VMSTIME fi2$q_expdate; + VMSTIME fi2$q_bakdate; char fi2$t_filenamext[66]; }; struct HEAD { - u_byte fh2$b_idoffset; - u_byte fh2$b_mpoffset; - u_byte fh2$b_acoffset; - u_byte fh2$b_rsoffset; - u_word fh2$w_seg_num; - u_word fh2$w_struclev; + vmsbyte fh2$b_idoffset; + vmsbyte fh2$b_mpoffset; + vmsbyte fh2$b_acoffset; + vmsbyte fh2$b_rsoffset; + vmsword fh2$w_seg_num; + vmsword fh2$w_struclev; struct fiddef fh2$w_fid; struct fiddef fh2$w_ext_fid; struct RECATTR fh2$w_recattr; - u_long fh2$l_filechar; - u_word fh2$w_reserved1; - u_byte fh2$b_map_inuse; - u_byte fh2$b_acc_mode; + vmslong fh2$l_filechar; + vmsword fh2$w_reserved1; + vmsbyte fh2$b_map_inuse; + vmsbyte fh2$b_acc_mode; struct UIC fh2$l_fileowner; - u_word fh2$w_fileprot; + vmsword fh2$w_fileprot; struct fiddef fh2$w_backlink; - u_byte fh2$b_journal; - u_byte fh2$b_ru_active; - u_word fh2$w_reserved2; - u_long fh2$l_highwater; - u_byte fh2$b_reserved3[8]; - u_byte fh2$r_class_prot[20]; - u_byte fh2$r_restofit[402]; - u_word fh2$w_checksum; + vmsbyte fh2$b_journal; + vmsbyte fh2$b_ru_active; + vmsword fh2$w_reserved2; + vmslong fh2$l_highwater; + vmsbyte fh2$b_reserved3[8]; + vmsbyte fh2$r_class_prot[20]; + vmsbyte fh2$r_restofit[402]; + vmsword fh2$w_checksum; }; +struct SCB { + vmsword scb$w_struclev; + vmsword scb$w_cluster; + vmslong scb$l_volsize; + vmslong scb$l_blksize; + vmslong scb$l_sectors; + vmslong scb$l_tracks; + vmslong scb$l_cylinders; + vmslong scb$l_status; + vmslong scb$l_status2; + vmsword scb$w_writecnt; + char scb$t_volockname[12]; + VMSTIME scb$q_mounttime; + vmsword scb$w_backrev; + vmslong scb$q_genernum[2]; + char scb$b_reserved[446]; + vmsword scb$w_checksum; +}; -struct EXT { - unsigned phylen; - unsigned phyblk; -}; /* Physical extent entry */ - +#ifdef __ALPHA +#pragma member_alignment restore +#endif #define EXTMAX 20 struct WCB { struct CACHE cache; unsigned loblk,hiblk; /* Range of window */ - unsigned hd_base; /* File blocks prior to header */ - unsigned extcount; /* Extents in use */ - struct EXT ext[EXTMAX]; /* Mapping extents */ - struct fiddef hd_fid; /* Header info to create other WCBs */ + unsigned hd_basevbn; /* File blocks prior to header */ + unsigned hd_seg_num; /* Header segment number */ + struct fiddef hd_fid; /* Header FID */ + unsigned short extcount; /* Extents in use */ + unsigned phylen[EXTMAX]; + unsigned phyblk[EXTMAX]; + unsigned char rvn[EXTMAX]; }; /* Window control block */ @@ -170,6 +202,8 @@ struct VIOC { }; /* Chunk of a file */ +#define FCB_WRITE 1 /* FCB open for write... */ + struct FCB { struct CACHE cache; struct VCB *vcb; /* Volume this file is for */ @@ -177,9 +211,10 @@ struct FCB { struct HEAD *head; /* Pointer to header block */ struct WCB *wcb; /* Window control block tree */ struct VIOC *vioc; /* Virtual I/O chunk tree */ - unsigned modmask; /* headvioc chunk modmask */ + unsigned headvbn; /* vbn for file header */ unsigned hiblock; /* Highest block mapped */ unsigned highwater; /* First high water block */ + unsigned char status; /* FCB status bits */ unsigned char rvn; /* Initial file relative volume */ }; /* File control block */ @@ -197,13 +232,15 @@ struct DIRCACHE { struct VCB { unsigned status; /* Volume status */ unsigned devices; /* Number of volumes in set */ - struct HEAD *idxboot; /* Pointer to index file boot header */ struct FCB *fcb; /* File control block tree */ struct DIRCACHE *dircache; /* Directory cache tree */ struct VCBDEV { struct DEV *dev; /* Pointer to device info */ struct FCB *idxfcb; /* Index file control block */ struct FCB *mapfcb; /* Bitmap file control block */ + unsigned clustersize; /* Cluster size of the device */ + unsigned max_cluster; /* Total clusters on the device */ + unsigned free_clusters; /* Free clusters on disk volume */ struct HOME home; /* Volume home block */ } vcbdev[1]; /* List of volumes devices */ }; /* Volume control block */ @@ -216,11 +253,10 @@ struct DEV { unsigned status; /* Device physical status */ unsigned sectors; /* Device physical sectors */ unsigned sectorsize; /* Device physical sectorsize */ - int devlen; /* Length of device name */ char devnam[1]; /* Device name */ }; /* Device information */ - +void fid_copy(struct fiddef *dst,struct fiddef *src,unsigned rvn); unsigned device_lookup(unsigned devlen,char *devnam,int create,struct DEV **retdev); unsigned dismount(struct VCB *vcb); @@ -231,7 +267,12 @@ unsigned deaccessfile(struct FCB *fcb); unsigned accessfile(struct VCB *vcb,struct fiddef *fid, struct FCB **fcb,unsigned wrtflg); -unsigned deaccesschunk(struct VIOC *vioc,unsigned modmask,int reuse); +unsigned deaccesschunk(struct VIOC *vioc,unsigned wrtvbn,int wrtblks,int reuse); unsigned accesschunk(struct FCB *fcb,unsigned vbn,struct VIOC **retvioc, - char **retbuff,unsigned *retblocks,unsigned wrtblks, - unsigned *retmodmask); + char **retbuff,unsigned *retblocks,unsigned wrtblks); +unsigned access_extend(struct FCB *fcb,unsigned blocks,unsigned contig); +unsigned update_freecount(struct VCBDEV *vcbdev,unsigned *retcount); +unsigned update_create(struct VCB *vcb,struct fiddef *did,char *filename, + struct fiddef *fid,struct FCB **fcb); +unsigned update_extend(struct FCB *fcb,unsigned blocks,unsigned contig); +unsigned short checksum(vmsword *block); diff --git a/extracters/ods2/build.com b/extracters/ods2/build.com index 34da25b..3b195b1 100644 --- a/extracters/ods2/build.com +++ b/extracters/ods2/build.com @@ -1,37 +1,41 @@ -$ gccflag := 'cc' -$ if f$extract(0,3,gccflag).nes."GCC" then gccflag="" -$ -$ if gccflag.nes."" -$ then p1="/optim=level=3/warn=all"+p1 -$ else p1="/warn=enabl=(defunct,obsolescent,questcode,uninit,unused)"+p1 -$ endif -$ -$ default=f$parse(f$environment("PROCEDURE"),,,"DEVICE","SYNTAX_ONLY")+ - - f$parse(f$environment("PROCEDURE"),,,"DIRECTORY","SYNTAX_ONLY") -$ set def 'default' -$ -$ call cc ods2 'p1' -$ call cc rms 'p1' -$ call cc direct 'p1' -$ call cc access 'p1' -$ call cc device 'p1' -$ call cc cache 'p1' -$ call cc phyvms 'p1' -$ call cc vmstime 'p1' -$ -$ write sys$error "''f$time()' Linking..." -$ if gccflag.nes."" -$ then library = ",vaxcrtl.tmp/option" -$ create vaxcrtl.tmp -sys$share:vaxcrtl/share -$ endif -$ link 'p2' ods2,rms,direct,access,device,cache,phyvms,vmstime 'library' -$ write sys$error "''f$time()' Done" -$ exit -$ -$cc: subroutine -$ if f$search(p1+".obj;").nes."" then if f$cvtime(f$file(p1+".obj;","CDT")).ges.f$cvtime(f$file(p1+".c;","CDT")) then exit -$ write sys$error "''f$time()' Compiling ''p1'..." -$ cc 'p2' 'p1' -$ exit -$ endsubroutine +$ gccflag := 'cc' +$ if f$extract(0,3,gccflag).nes."GCC" then gccflag="" +$ +$ if gccflag.nes."" +$ then p1="/optim=level=3/warn=all"+p1 +$ else p1="/warn=enabl=(defunct,obsolescent,questcode,uninit,unused)"+p1 +$ endif +$ +$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" .and. gccflag.eqs."" +$ then p1 = "/INCLUDE=SYS$DISK:[]"+p1 +$ endif +$ default=f$parse(f$environment("PROCEDURE"),,,"DEVICE","SYNTAX_ONLY")+ - + f$parse(f$environment("PROCEDURE"),,,"DIRECTORY","SYNTAX_ONLY") +$ set def 'default' +$ +$ call cc ods2 'p1' +$ call cc rms 'p1' +$ call cc direct 'p1' +$ call cc access 'p1' +$ call cc device 'p1' +$ call cc cache 'p1' +$ call cc phyvms 'p1' +$ call cc update 'p1' +$ call cc vmstime 'p1' +$ +$ write sys$error "''f$time()' Linking..." +$ if gccflag.nes."" .and. f$getsyi("HW_MODEL").lt.1024 +$ then library = ",vaxcrtl.tmp/option" +$ create vaxcrtl.tmp +sys$share:vaxcrtl/share +$ endif +$ link 'p2' ods2,rms,direct,access,device,cache,phyvms,vmstime,update 'library' +$ write sys$error "''f$time()' Done" +$ exit +$ +$cc: subroutine +$ if f$search(p1+".obj;").nes."" then if f$cvtime(f$file(p1+".obj;","CDT")).ges.f$cvtime(f$file(p1+".c;","CDT")) then exit +$ write sys$error "''f$time()' Compiling ''p1'..." +$ cc 'p2' 'p1' +$ exit +$ endsubroutine diff --git a/extracters/ods2/cache.c b/extracters/ods2/cache.c index c6374e6..fc3d78f 100644 --- a/extracters/ods2/cache.c +++ b/extracters/ods2/cache.c @@ -1,4 +1,4 @@ -/* Cache.c v1.2 Caching control routines */ +/* Cache.c v1.3 Caching control routines */ /* This is part of ODS2 written by Paul Nankervis, @@ -10,24 +10,41 @@ the contibution of the original author. */ -/* Caching seems to have a big impact on performance!!! - This version based on number of objects - probably - should change it to use space occupied by objects. - Currently use vanilla binary trees - could either - use hashing or balanced trees for better performance. */ +/* + The theory is that all cachable objects share a common cache pool. + Any object with a reference count of zero is a candidate for + destruction. All cacheable objects have a 'struct CACHE' as the + first item of the object so that cache pointers and object pointers + are 'interchangeable'. All cache objects are also part of a binary + tree so that they can be located. There are many instances of these + binary trees: for files on a volume, file windows, file chunks + (segments) etc. Also each object can have an object manager: a + routine to handle special object deletion requirements (for example + to remove all file chunks before removing a file), or to flush + objects (write modified chunks to disk). -/* The theory is that all cachable objects share a common - cache pool. Any object with a reference count of zero - is a candidate for destruction. All cacheable objects - have a 'struct CACHE' as the first item of the object - so that cache pointers and object pointers are interchangeable. - All cache objects are also part of a binary tree so that - they can be located. There are many instances of these - binary trees: for files on a volume, for chunks (segments) - of files, etc. Also each object can have an object manager: - a routine to handle special object deletion requirements - (for example to remove all file chunks before removing a - file), or to flush objects (write modified chunks to disk). */ + The main routines is cache_find() which is used to search for and + place objects in a binary tree which is located by a tree pointer. + cache_touch() and cache_untouch() are used to bump and decrement + reference counts. Any object with a reference count of zero is a + candidate for destruction - but if it requires special action + before it is destroyed, such as deleting a subtree, flushing data + to disk, etc, then it should have an 'object manager' function + assigned which will be called at deletion time to take care of these + needs. + + This version of the cache routines attempts to maintain binary tree + balance by dynamically changing tree shape during search functions. + All objects remain in the binary tree until destruction so that they + can be re-used at any time. Objects with a zero reference count are + special in that they are kept in a 'least recently used' linked list. + When the reference count is decemented a flag is used to indicate + whether the object is likely to be referenced again so that the object + can be put in the 'correct' end of this list. + + Note: These routines are 'general' in that do not know anything + about ODS2 objects or structures.... +*/ #include @@ -37,373 +54,308 @@ #include "cache.h" -#define DEBUG on +#define DEBUG /* Debug mode? */ +#define IMBALANCE 5 /* Tree imbalance limit */ +#define CACHELIM 256 /* Free object limit */ +#define CACHEGOAL 128 /* Free object goal */ -/* Set limits for number of unaccessed cache entries... */ - -#define CACHELIM 64 -#define CACHEGOAL 25 - -int cachesearches = 0; +int cachefinds = 0; int cachecreated = 0; -int cachedeleted = 0; +int cachepurges = 0; int cachepeak = 0; int cachecount = 0; int cachefreecount = 0; +int cachedeletes = 0; -struct CACHE cachelist = {NULL,NULL,NULL,&cachelist,&cachelist,NULL,0,0,1}; +int cachedeleteing = 0; /* Cache deletion in progress... */ + +struct CACHE lrulist = {&lrulist,&lrulist,NULL,NULL,NULL,NULL,0,0,1,0}; -/* cacheshow - to print cache statistics */ +/* cache_show() - to print cache statistics */ -void cacheshow(void) +void cache_show(void) { - printf("CACHESHOW Searches: %d Created: %d Peak: %d Count: %d Free: %d\n", - cachesearches,cachecreated,cachepeak,cachecount,cachefreecount); + printf("CACHE_SHOW Find %d Create %d Purge %d Peak %d Count %d Free %d\n", + cachefinds,cachecreated,cachepurges,cachepeak,cachecount,cachefreecount); + if (cachecreated - cachedeletes != cachecount) printf(" - Deleted %d\n",cachedeletes); } -void cachedump(void) -{ - register struct CACHE *cacheobj = cachelist.lstcache; - printf("%8.8s %8.8s %8.8s %8.8s %8.8s %8.8s %8.8s cachelist\n","Object", - "Parent","Left","Right","Value","Status","Count"); - while (cacheobj != &cachelist) { - printf("%8p %8p %8p %8p %8x %8x %8d\n", - cacheobj,cacheobj->parent,cacheobj->left,cacheobj->right, - cacheobj->keyval,cacheobj->status,cacheobj->refcount); - cacheobj = cacheobj->lstcache; - } -} +/* cache_refcount() - compute reference count for cache subtree... */ - -/* cacheprint - debugging tool to print out a cache subtree... */ - -void cacheprint(struct CACHE *cacheobj,int level) -{ - if (cacheobj != NULL) { - int i; - cacheprint(cacheobj->left,level + 1); - for (i = 0; i < level; i++) printf(" "); - printf("%8p %8x %8x %d\n", - cacheobj,cacheobj->keyval,cacheobj->status,cacheobj->refcount); - cacheprint(cacheobj->right,level + 1); - } -} - - -/* cacherefcount - compute reference count for cache subtree... */ - -int cacherefcount(struct CACHE *cacheobj) +int cache_refcount(struct CACHE *cacheobj) { register int refcount = 0; if (cacheobj != NULL) { - if (cacheobj->left != NULL) refcount += cacherefcount(cacheobj->left); - if (cacheobj->right != NULL) refcount += cacherefcount(cacheobj->right); - refcount += cacheobj->refcount; + refcount = cacheobj->refcount; + if (cacheobj->left != NULL) refcount += cache_refcount(cacheobj->left); + if (cacheobj->right != NULL) refcount += cache_refcount(cacheobj->right); } return refcount; } -/* cachefree - blow away item from cache - allow item to select a proxy (!) +/* cache_delete() - blow away item from cache - allow item to select a proxy (!) and adjust 'the tree' containing the item. */ -int freeactive = 0; /* In case object managers re-call cachefree... :-( */ - -struct CACHE *cachefree(struct CACHE *cacheobj) +struct CACHE *cache_delete(struct CACHE *cacheobj) { - if (cacheobj->refcount != 0) { - char str[100]; - printf("cachelist, object to delete still inuse?\n"); - printf("%8p %8p %8p %8p %8x %8x %8d\n", - cacheobj,cacheobj->parent,cacheobj->left,cacheobj->right, - cacheobj->keyval,cacheobj->status,cacheobj->refcount); - printf("Type RETURN: "); - fgets(str, sizeof(str)-1, stdin); - return NULL; - } else { + while (cacheobj->objmanager != NULL) { register struct CACHE *proxyobj; - while (cacheobj->objmanager != NULL) { - freeactive = 1; - proxyobj = (*cacheobj->objmanager) (cacheobj); - freeactive = 0; - if (proxyobj == NULL) return NULL; - if (proxyobj == cacheobj) break; - cacheobj = proxyobj; - } - if ((cacheobj->status & CACHE_MODIFIED) && cacheobj->objmanager == NULL) - printf("cachelist No manager to write modified cache\n"); - cacheobj->lstcache->nxtcache = cacheobj->nxtcache; - cacheobj->nxtcache->lstcache = cacheobj->lstcache; - if (cacheobj->parent != NULL) { /* Check if in tree... */ - if (cacheobj->left == NULL) { - if (cacheobj->right == NULL) { - *(cacheobj->parent) = NULL; - } else { - cacheobj->right->parent = cacheobj->parent; - *(cacheobj->parent) = cacheobj->right; - } - } else { - if (cacheobj->right == NULL) { - cacheobj->left->parent = cacheobj->parent; - *(cacheobj->parent) = cacheobj->left; - } else { - register struct CACHE *leftpath = cacheobj->left; - register struct CACHE *rightpath = cacheobj->right; - while (1) { - if (leftpath->right == NULL) { - leftpath->right = cacheobj->right; - cacheobj->right->parent = &leftpath->right; - cacheobj->left->parent = cacheobj->parent; - *(cacheobj->parent) = cacheobj->left; - break; - } else { - if (rightpath->left == NULL) { - rightpath->left = cacheobj->left; - cacheobj->left->parent = &rightpath->left; - cacheobj->right->parent = cacheobj->parent; - *(cacheobj->parent) = cacheobj->right; - break; - } else { - leftpath = leftpath->right; - rightpath = rightpath->left; - } - } - } - } - } - } - if (--cachecount < 0) printf("cachelist, cache current too small\n"); - cachefreecount--; - cachedeleted--; -#ifdef DEBUG - cacheobj->parent = NULL; - cacheobj->left = NULL; - cacheobj->right = NULL; - cacheobj->nxtcache = NULL; - cacheobj->lstcache = NULL; - cacheobj->objmanager = NULL; - cacheobj->keyval = 0; - cacheobj->status = 0; - cacheobj->refcount = 0; -#endif - free(cacheobj); - return cacheobj; + cachedeleteing = 1; + proxyobj = (*cacheobj->objmanager) (cacheobj,0); + cachedeleteing = 0; + if (proxyobj == NULL) return NULL; + if (proxyobj == cacheobj) break; + cacheobj = proxyobj; } -} - - -/* cachepurge - trim size of free list */ - -void cachepurge() -{ - register struct CACHE *cacheobj = cachelist.lstcache; - while (cachefreecount > CACHEGOAL && cacheobj != &cachelist) { - register struct CACHE *lastobj = cacheobj->lstcache; #ifdef DEBUG - if (cacheobj->lstcache->nxtcache != cacheobj || - cacheobj->nxtcache->lstcache != cacheobj || - *(cacheobj->parent) != cacheobj) { - printf("CACHE pointers in bad shape! %p %p %p - %p\n", - cacheobj->lstcache->nxtcache,cacheobj,cacheobj->nxtcache->lstcache,*(cacheobj->parent)); - } + if (cachedeleteing != 0) printf("CACHE deletion while delete in progress\n"); #endif - if (cacheobj->refcount == 0) { - if (cachefree(cacheobj) != lastobj) cacheobj = lastobj; + if (cacheobj->refcount != 0) { +#ifdef DEBUG + printf("CACHE attempt to delete referenced object %d:%d\n", + cacheobj->objtype,cacheobj->hashval); +#endif + return NULL; + } + cacheobj->lastlru->nextlru = cacheobj->nextlru; + cacheobj->nextlru->lastlru = cacheobj->lastlru; + if (cacheobj->left == NULL) { + if (cacheobj->right == NULL) { + *(cacheobj->parent) = NULL; } else { - cacheobj = lastobj; + cacheobj->right->parent = cacheobj->parent; + *(cacheobj->parent) = cacheobj->right; } - } -} - - - -/* cacheflush - flush modified entries in cache */ - -void cacheflush() -{ - register struct CACHE *cacheobj = cachelist.lstcache; - while (cacheobj != &cachelist) { - if (cacheobj->status & CACHE_MODIFIED) { - if (cacheobj->objmanager != NULL) { - (*cacheobj->objmanager) (cacheobj); - } else { - printf("CACHEFLUSH No manager to write modified cache\n"); + } else { + if (cacheobj->right == NULL) { + cacheobj->left->parent = cacheobj->parent; + *(cacheobj->parent) = cacheobj->left; + } else { + register struct CACHE *path = cacheobj->right; + if (path->left != NULL) { + do { + path = path->left; + } while (path->left != NULL); + *(path->parent) = path->right; + if (path->right != NULL) path->right->parent = path->parent; + path->right = cacheobj->right; + path->right->parent = &path->right; } + path->left = cacheobj->left; + path->left->parent = &path->left; + path->parent = cacheobj->parent; + *(cacheobj->parent) = path; + path->balance = 0; } - cacheobj = cacheobj->lstcache; - } -} - - -/* cachedelete - delete an object from cache */ - -struct CACHE *cachedelete(struct CACHE *cacheobj) -{ - if (cacheobj != NULL) { - register struct CACHE *cachedel; - do { - cachedel = cachefree(cacheobj); - } while (cachedel != NULL && cachedel != cacheobj); } + cachecount--; + cachefreecount--; + cachedeletes++; +#ifdef DEBUG + cacheobj->nextlru = NULL; + cacheobj->lastlru = NULL; + cacheobj->left = NULL; + cacheobj->right = NULL; + cacheobj->parent = NULL; + cacheobj->objmanager = NULL; + cacheobj->hashval = 0; + cacheobj->balance = 0; + cacheobj->refcount = 0; +#endif + free(cacheobj); return cacheobj; } +/* cache_purge() - trim size of free list */ -/* cachedeltree: delete cache subtree */ +void cache_purge(void) +{ + if (cachedeleteing == 0) { + register struct CACHE *cacheobj = lrulist.lastlru; + cachepurges++; + while (cachefreecount > CACHEGOAL && cacheobj != &lrulist) { + register struct CACHE *lastobj = cacheobj->lastlru; +#ifdef DEBUG + if (cacheobj->lastlru->nextlru != cacheobj || + cacheobj->nextlru->lastlru != cacheobj || + *(cacheobj->parent) != cacheobj) { + printf("CACHE pointers in bad shape!\n"); + } +#endif + if (cacheobj->refcount == 0) { + if (cache_delete(cacheobj) != lastobj) cacheobj = lastobj; + } else { + cacheobj = lastobj; + } + } + } +} -void cachedeltree(struct CACHE *cacheobj) + + +/* cache_flush() - flush modified entries in cache */ + +void cache_flush(void) +{ + register struct CACHE *cacheobj = lrulist.lastlru; + while (cacheobj != &lrulist) { + if (cacheobj->objmanager != NULL) { + (*cacheobj->objmanager) (cacheobj,1); + } + cacheobj = cacheobj->lastlru; + } +} + + +/* cache_remove() - delete all possible objects from cache subtree */ + +void cache_remove(struct CACHE *cacheobj) { if (cacheobj != NULL) { - if (cacheobj->left != NULL) cachedeltree(cacheobj->left); - if (cacheobj->right != NULL) cachedeltree(cacheobj->right); - if (cacheobj->refcount == 0) cachedelete(cacheobj); + if (cacheobj->left != NULL) cache_remove(cacheobj->left); + if (cacheobj->right != NULL) cache_remove(cacheobj->right); + if (cacheobj->refcount == 0) { + struct CACHE *delobj; + do { + delobj = cache_delete(cacheobj); + } while (delobj != NULL && delobj != cacheobj); + } } } +/* cache_touch() - to increase the access count on an object... */ - - -/* cacheuntouch - decrement object reference count */ - -unsigned cacheuntouch(struct CACHE *cacheobj,unsigned reuse,unsigned modflg) +void cache_touch(struct CACHE *cacheobj) { - if (cacheobj->refcount < 1) { - char str[100]; - printf("%8p %8p %8p %8p %8x %8x %8d\n", - cacheobj,cacheobj->parent,cacheobj->left,cacheobj->right, - cacheobj->keyval,cacheobj->status,cacheobj->refcount); - printf("CACHE untouch TOO FAR!\n"); - printf("Type RETURN: "); - fgets(str, sizeof(str), stdin); - return 64; - } else { - if (modflg) { - if ((cacheobj->status & CACHE_WRITE) == 0) return SS$_WRITLCK; - cacheobj->status |= CACHE_MODIFIED; - } - if (--cacheobj->refcount == 0) { - /* Move to new list position... */ - if (reuse == 0 && cacheobj != cachelist.lstcache) { - cacheobj->lstcache->nxtcache = cacheobj->nxtcache; - cacheobj->nxtcache->lstcache = cacheobj->lstcache; - cacheobj->nxtcache = &cachelist; - cacheobj->lstcache = cachelist.lstcache; - cachelist.lstcache->nxtcache = cacheobj; - cachelist.lstcache = cacheobj; - } - cacheobj->status &= ~CACHE_WRITE; - if (++cachefreecount > CACHELIM && freeactive == 0) cachepurge(); - } - } - return 1; -} - - -/* cachetouch - add one to reference count */ - -void cachetouch(struct CACHE *cacheobj) -{ - if (cacheobj->refcount++ < 1) { + if (cacheobj->refcount++ == 0) { #ifdef DEBUG - if (cacheobj->lstcache->nxtcache != cacheobj || - cacheobj->nxtcache->lstcache != cacheobj || - *(cacheobj->parent) != cacheobj) { - printf("CACHE pointers in bad shape! %p %p %p - %p\n", - cacheobj->lstcache->nxtcache,cacheobj,cacheobj->nxtcache->lstcache,*(cacheobj->parent)); + if (cacheobj->nextlru == NULL || cacheobj->lastlru == NULL) { + printf("CACHE LRU pointers corrupt!\n"); } #endif + cacheobj->nextlru->lastlru = cacheobj->lastlru; + cacheobj->lastlru->nextlru = cacheobj->nextlru; + cacheobj->nextlru = NULL; + cacheobj->lastlru = NULL; cachefreecount--; } - /* Move object to head of list... */ - if (cacheobj != cachelist.nxtcache) { - cacheobj->lstcache->nxtcache = cacheobj->nxtcache; - cacheobj->nxtcache->lstcache = cacheobj->lstcache; - cacheobj->lstcache = &cachelist; - cacheobj->nxtcache = cachelist.nxtcache; - cachelist.nxtcache->lstcache = cacheobj; - cachelist.nxtcache = cacheobj; - } } +/* cache_untouch() - to deaccess an object... */ -/* cachesearch - to find or create cache entries... +void cache_untouch(struct CACHE *cacheobj,int recycle) +{ + if (cacheobj->refcount > 0) { + if (--cacheobj->refcount == 0) { + if (++cachefreecount >= CACHELIM) cache_purge(); +#ifdef DEBUG + if (cacheobj->nextlru != NULL || cacheobj->lastlru != NULL) { + printf("CACHE LRU pointers corrupt\n"); + } +#endif + if (recycle) { + cacheobj->nextlru = lrulist.nextlru; + cacheobj->lastlru = &lrulist; + cacheobj->nextlru->lastlru = cacheobj; + lrulist.nextlru = cacheobj; + } else { + cacheobj->lastlru = lrulist.lastlru; + cacheobj->nextlru = &lrulist; + cacheobj->lastlru->nextlru = cacheobj; + lrulist.lastlru = cacheobj; + } + } +#ifdef DEBUG + } else { + printf("CACHE untouch limit exceeded\n"); +#endif + } +} + +/* cache_find() - to find or create cache entries... The grand plan here was to use a hash code as a quick key and call a compare function for duplicates. So far no data type actually works like this - they either have a unique binary key, or all records rely on the compare function - sigh! - Never mind, the potential is there! :-) */ + Never mind, the potential is there! :-) -void *cachesearch(void **root,unsigned keyval,unsigned keylen,void *key, - int (*cmpfunc) (unsigned keylen,void *key,void *node), - unsigned *createsize) + This version will call a creation function to allocate and + initialize an object if it is not found. +*/ + +void *cache_find(void **root,unsigned hashval,void *keyval,unsigned *retsts, + int (*compare_func) (unsigned hashval,void *keyval,void *node), + void *(*create_func) (unsigned hashval,void *keyval,unsigned *retsts)) { - register struct CACHE *parentobj = NULL; register struct CACHE *cacheobj,**parent = (struct CACHE **) root; - cachesearches++; + cachefinds++; while ((cacheobj = *parent) != NULL) { - parentobj = cacheobj; - if (cacheobj->keyval == keyval) { - register int cmp = 0; - if (cmpfunc != NULL) - cmp = (*cmpfunc) (keylen,key,(void *) cacheobj); - if (cmp == 0) { - cachetouch(cacheobj); - return cacheobj; + register int cmp = hashval - cacheobj->hashval; +#ifdef DEBUG + if (cacheobj->parent != parent) { + printf("CACHE Parent pointer is corrupt\n"); + } +#endif + if (cmp == 0 && compare_func != NULL) cmp = (*compare_func) (hashval,keyval,cacheobj); + if (cmp == 0) { + cache_touch(cacheobj); + if (retsts != NULL) *retsts = SS$_NORMAL; + return cacheobj; + } + if (cmp < 0) { +#ifdef IMBALANCE + register struct CACHE *left_path = cacheobj->left; + if (left_path != NULL && cacheobj->balance-- < -IMBALANCE) { + cacheobj->left = left_path->right; + if (cacheobj->left != NULL) cacheobj->left->parent = &cacheobj->left; + left_path->right = cacheobj; + cacheobj->parent = &left_path->right; + *parent = left_path; + left_path->parent = parent; + cacheobj->balance = 0; } else { - if (cmp < 0) { - parent = &cacheobj->left; - } else { - parent = &cacheobj->right; - } + parent = &cacheobj->left; } } else { - if (cacheobj->keyval < keyval) { - parent = &cacheobj->left; + register struct CACHE *right_path = cacheobj->right; + if (right_path != NULL && cacheobj->balance++ > IMBALANCE) { + cacheobj->right = right_path->left; + if (cacheobj->right != NULL) cacheobj->right->parent = &cacheobj->right; + right_path->left = cacheobj; + cacheobj->parent = &right_path->left; + *parent = right_path; + right_path->parent = parent; + cacheobj->balance = 0; } else { parent = &cacheobj->right; } +#else + parent = &cacheobj->left; + } else { + parent = &cacheobj->right; +#endif } } - if (*createsize > sizeof(struct CACHE)) { - cacheobj = (struct CACHE *) malloc(*createsize); + if (create_func == NULL) { + if (retsts != NULL) *retsts = SS$_ITEMNOTFOUND; + } else { + cacheobj = (*create_func) (hashval,keyval,retsts); if (cacheobj != NULL) { - cacheobj->parent = parent; + cacheobj->nextlru = NULL; + cacheobj->lastlru = NULL; cacheobj->left = NULL; cacheobj->right = NULL; - cacheobj->objmanager = NULL; - cacheobj->keyval = keyval; - cacheobj->status = 0; + cacheobj->parent = parent; + cacheobj->hashval = hashval; + cacheobj->balance = 0; cacheobj->refcount = 1; *parent = cacheobj; - *createsize = 0; cachecreated++; - /* Add to cache list... */ - cacheobj->lstcache = &cachelist; - cacheobj->nxtcache = cachelist.nxtcache; - cachelist.nxtcache->lstcache = cacheobj; - cachelist.nxtcache = cacheobj; - if (parentobj != NULL) { - /* Attempt to mix up the tree a little... */ - if (parentobj->left == NULL) { - *parentobj->parent = cacheobj; - cacheobj->parent = parentobj->parent; - parentobj->parent = &cacheobj->left; - cacheobj->left = parentobj; - parentobj->right = NULL; - } else { - if (parentobj->right == NULL) { - *parentobj->parent = cacheobj; - cacheobj->parent = parentobj->parent; - parentobj->parent = &cacheobj->right; - cacheobj->right = parentobj; - parentobj->left = NULL; - } - } - } if (cachecount++ >= cachepeak) cachepeak = cachecount; } } diff --git a/extracters/ods2/cache.h b/extracters/ods2/cache.h index 39add67..e2516cc 100644 --- a/extracters/ods2/cache.h +++ b/extracters/ods2/cache.h @@ -1,4 +1,4 @@ -/* Cache.h v1.2 Definitions for cache routines */ +/* Cache.h v1.3 Definitions for cache routines */ /* This is part of ODS2 written by Paul Nankervis, @@ -10,35 +10,38 @@ the contibution of the original author. */ -#ifndef CACHE_WRITE +#ifndef CACHE_LOADED -#define CACHE_WRITE 1 -#define CACHE_MODIFIED 2 +#define CACHE_LOADED + +#ifndef VAXC /* Stupid VAX C doesn't allow "signed" keyword */ +#define signed signed +#else +#define signed +#endif struct CACHE { - struct CACHE **parent; - struct CACHE *left; - struct CACHE *right; - struct CACHE *nxtcache; - struct CACHE *lstcache; - struct CACHE *(*objmanager) (struct CACHE * cacheobj); - unsigned keyval; - unsigned status; - int refcount; + struct CACHE *nextlru; /* next object on least recently used list */ + struct CACHE *lastlru; /* last object on least recently used list */ + struct CACHE *left; /* left branch of binary tree */ + struct CACHE *right; /* right branch of binary tree */ + struct CACHE **parent; /* address of pointer to this object */ + void *(*objmanager) (struct CACHE * cacheobj,int flushonly); + unsigned hashval; /* object hash value */ + short refcount; /* object reference count */ + signed char balance; /* object tree imbalance factor */ + signed char objtype; /* object type (for debugging) */ }; -void cacheshow(void); -void cachedump(void); -void cacheprint(struct CACHE *cacheobj,int level); -void cacheflush(void); -int cacherefcount(struct CACHE *cacheobj); -void cachedeltree(struct CACHE *cacheobj); -void cachetouch(struct CACHE *cacheobj); -unsigned cacheuntouch(struct CACHE *cacheobj,unsigned reuse,unsigned modflg); -struct CACHE *cachefree(struct CACHE *cacheobj); -struct CACHE *cachedelete(struct CACHE *cacheobj); -struct CACHE *cachemake(struct CACHE **parent,unsigned length); -void *cachesearch(void **root,unsigned keyval,unsigned keylen,void *key, - int (*cmpfunc) (unsigned keylen,void *key,void *node), - unsigned *createsize); +void cache_show(void); +int cache_refcount(struct CACHE *cacheobj); +struct CACHE *cache_delete(struct CACHE *cacheobj); +void cache_purge(void); +void cache_flush(void); +void cache_remove(struct CACHE *cacheobj); +void cache_touch(struct CACHE * cacheobj); +void cache_untouch(struct CACHE * cacheobj,int recycle); +void *cache_find(void **root,unsigned hashval,void *keyval,unsigned *retsts, + int (*compare_func) (unsigned hashval,void *keyval,void *node), + void *(*create_func) (unsigned hashval,void *keyval,unsigned *retsts)); #endif diff --git a/extracters/ods2/descrip.h b/extracters/ods2/descrip.h index eeb09b6..8c524c7 100644 --- a/extracters/ods2/descrip.h +++ b/extracters/ods2/descrip.h @@ -1,4 +1,4 @@ -/* Descrip.h v1.2 Definitions for descriptors */ +/* Descrip.h v1.4 Definitions for descriptors */ /* This is part of ODS2 written by Paul Nankervis, @@ -8,27 +8,41 @@ VMS community to use. However all derived works must maintain comments in their source to acknowledge the contibution of the original author. + + 1.4 Changed declarations NOT to define DOLLAR identifiers + unless DOLLAR is defined (some compilers can't handle $'s!) + Fixed definition of _DESCRIPTOR(). + 1.4A Changed default DOLLAR handling to include DOLLAR + identifers unless NO_DOLLAR is defined + (ie #ifdef DOLLAR to #ifndef NO_DOLLAR) */ +#ifndef _DESCRIPTOR -#if defined(VMS) && !defined(__GNUC__) +#ifndef NO_DOLLAR +#ifndef $DESCRIPTOR +#define DSC$K_DTYPE_T DSC_K_DTYPE_T +#define DSC$K_CLASS_S DSC_K_CLASS_S +#define dsc$descriptor dsc_descriptor +#define dsc$w_length dsc_w_length +#define dsc$b_dtype dsc_b_dtype +#define dsc$b_class dsc_b_class +#define dsc$a_pointer dsc_a_pointer +#define $DESCRIPTOR _DESCRIPTOR +#endif +#endif -#include +#define DSC_K_DTYPE_T 0 +#define DSC_K_CLASS_S 0 -#else - -#ifndef DSC$K_DTYPE_T -#define DSC$K_DTYPE_T 0 -#define DSC$K_CLASS_S 0 - -struct dsc$descriptor { - unsigned short dsc$w_length; - unsigned char dsc$w_type; - unsigned char dsc$w_class; - char *dsc$a_pointer; +struct dsc_descriptor { + unsigned short dsc_w_length; + unsigned char dsc_b_dtype; + unsigned char dsc_b_class; + char *dsc_a_pointer; }; -#define $DESCRIPTOR(string,name) struct dsc$descriptor name = {sizeof(sring)-1,0,0,string}; +#define _DESCRIPTOR(symbol,value) \ + struct dsc_descriptor symbol = {sizeof(value)-1,0,0,value} #endif -#endif diff --git a/extracters/ods2/descrip.mms b/extracters/ods2/descrip.mms new file mode 100644 index 0000000..35ae0e7 --- /dev/null +++ b/extracters/ods2/descrip.mms @@ -0,0 +1,58 @@ +# +# MMS (MMK) description file to build ODS2 for VMS +# +# To compile on VAX using VAX C, use: +# +# $ mmk/macro=vaxc=1 +# +# +.IFDEF EXE +.ELSE +EXE = .EXE +OBJ = .OBJ +OLB = .OLB +.ENDIF + +.IFDEF __DEBUG__ +CFLAGS = $(CFLAGS)/DEBUG/NOOPTIMIZE +LINKFLAGS = $(LINKFLAGS)/DEBUG +.ELSE +LINKFLAGS = $(LINKFLAGS)/NOTRACE +.ENDIF + +.IFDEF __VAXC__ +CFLAGS = $(CFLAGS)/INCLUDE=SYS$DISK:[] +OPTFILE = ,VAXCRTL.OPT +OPTIONS = $(OPTFILE)/OPTIONS +.ELSE +OPTFILE = +OPTIONS = +.ENDIF + +OBJS = ODS2,RMS,DIRECT,ACCESS,DEVICE,CACHE,PHYVMS,UPDATE,VMSTIME + +ODS2$(EXE) : ODS2$(OLB)($(OBJS))$(OPTFILE) + $(LINK)$(LINKFLAGS) ODS2$(OLB)/INCLUDE=($(OBJS))$(OPTIONS) + +vmstime$(obj) : vmstime.c vmstime.h + +cache$(obj) : cache.c cache.h ssdef.h + +phyvms$(obj) : phyvms.c phyio.h ssdef.h + +device$(obj) : device.c ssdef.h access.h phyio.h + +access$(obj) : access.c ssdef.h access.h phyio.h + +update$(obj) : update.c ssdef.h access.h + +direct$(obj) : direct.c direct.h access.h fibdef.h descrip.h ssdef.h + +rms$(obj) : rms.c rms.h direct.h access.h fibdef.h descrip.h ssdef.h + +ods2$(obj) : ods2.c ssdef.h descrip.h access.h rms.h + +VAXCRTL.OPT : + @ open/write tmp $(MMS$TARGET) + @ write tmp "SYS$SHARE:VAXCRTL.EXE/SHARE" + @ close tmp diff --git a/extracters/ods2/device.c b/extracters/ods2/device.c index 6b1cc91..054f70f 100644 --- a/extracters/ods2/device.c +++ b/extracters/ods2/device.c @@ -1,4 +1,4 @@ -/* Device.c v1.2 Module to remember and find devices...*/ +/* Device.c v1.3 Module to remember and find devices...*/ /* This is part of ODS2 written by Paul Nankervis, @@ -23,63 +23,72 @@ #include "access.h" #include "phyio.h" +/* device_create() creates a device object... */ -int devcmp(unsigned keylen,void *key,void *node) +void *device_create(unsigned devsiz,void *keyval,unsigned *retsts) +{ + register char *devnam = (char *) keyval; + register struct DEV *dev = (struct DEV *) malloc(sizeof(struct DEV) + devsiz + 2); + if (dev == NULL) { + *retsts = SS$_INSFMEM; + } else { + register unsigned sts; + struct phyio_info info; + dev->cache.objmanager = NULL; + dev->cache.objtype = 1; + memcpy(dev->devnam,devnam,devsiz); + memcpy(dev->devnam + devsiz,":",2); + sts = phyio_init(devsiz + 1,dev->devnam,&dev->handle,&info); + *retsts = sts; + if (sts & 1) { + dev->vcb = NULL; + dev->status = info.status; + dev->sectors = info.sectors; + dev->sectorsize = info.sectorsize; + } else { + free(dev); + dev = NULL; + } + } + return dev; +} + +/* device_compare() compares a device name to that of a device object... */ + +int device_compare(unsigned keylen,void *keyval,void *node) { register struct DEV *devnode = (struct DEV *) node; - register int cmp = keylen - devnode->devlen; - if (cmp == 0) { - register unsigned len = keylen; - register char *keynam = (char *) key; - register char *devnam = devnode->devnam; - while (len-- > 0) { - cmp = toupper(*keynam++) - toupper(*devnam++); - if (cmp != 0) break; - } + register int cmp = 0; + register int len = keylen; + register char *keynam = (char *) keyval; + register char *devnam = devnode->devnam; + while (len-- > 0) { + cmp = toupper(*keynam++) - toupper(*devnam++); + if (cmp != 0) break; } return cmp; } +/* device_lookup() is to to find devices... */ + struct DEV *dev_root = NULL; unsigned device_lookup(unsigned devlen,char *devnam, int create,struct DEV **retdev) { register struct DEV *dev; - register unsigned sts,devsiz = 0; - unsigned devcreate = 0; + unsigned sts = 1,devsiz = 0; while (devsiz < devlen) { if (devnam[devsiz] == ':') break; devsiz++; } - if (create) devcreate = sizeof(struct DEV) + devsiz + 2; - dev = (struct DEV *) cachesearch((void **) &dev_root,0,devsiz, - (void *) devnam,devcmp,&devcreate); + dev = (struct DEV *) cache_find((void **) &dev_root,devsiz,devnam,&sts, + device_compare,create ? device_create : NULL); if (dev == NULL) { - if (create) { - sts = SS$_INSFMEM; - } else { - sts = SS$_NOSUCHDEV; - } + if (sts == SS$_ITEMNOTFOUND) sts = SS$_NOSUCHDEV; } else { - struct phyio_info info; *retdev = dev; - if (create && (devcreate == 0)) { - memcpy(dev->devnam,devnam,devsiz); - memcpy(dev->devnam + devsiz,":",2); - dev->devlen = devsiz; - sts = phyio_init(devsiz + 1,dev->devnam,&dev->handle,&info); - if (sts & 1) { - dev->status = info.status; - dev->sectors = info.sectors; - dev->sectorsize = info.sectorsize; - } else { - cacheuntouch((struct CACHE *) dev,0,0); - cachefree((struct CACHE *) dev); - } - } else { - sts = 1; - } + sts = SS$_NORMAL; } return sts; } diff --git a/extracters/ods2/direct.c b/extracters/ods2/direct.c index 888af89..aa7abd6 100644 --- a/extracters/ods2/direct.c +++ b/extracters/ods2/direct.c @@ -1,4 +1,4 @@ -/* Direct.c v1.2 */ +/* Direct.c v1.3 */ /* This is part of ODS2 written by Paul Nankervis, @@ -13,13 +13,11 @@ /* This module does all directory file handling - mostly lookups of filenames in directory files... */ -/* This version takes relative version from last seen directory record - - this is no good if there are multiple directory records for a file! */ #include #include #include -#include +#include #include "ssdef.h" #include "descrip.h" #include "fibdef.h" @@ -27,40 +25,49 @@ #include "direct.h" #define DEBUGx on +#define BLOCKSIZE 512 +#define MAXREC (BLOCKSIZE - 2) -int directlookups = 0; -int directsearches = 0; -int directdels = 0; -int directchecks = 0; -int directmatches = 0; +/* Some statistical counters... */ + +int direct_lookups = 0; +int direct_searches = 0; +int direct_deletes = 0; +int direct_inserts = 0; +int direct_splits = 0; +int direct_checks = 0; +int direct_matches = 0; -/* directshow - to print directory statistics */ +/* direct_show - to print directory statistics */ -void directshow(void) +void direct_show(void) { - printf("DIRECTSHOW Lookups: %d Searches: %d Deletes: %d Checks: %d Matches: %d\n", - directlookups,directsearches,directdels,directchecks,directmatches); + printf("DIRECT_SHOW Lookups: %d Searches: %d Deletes: %d Inserts: %d Splits: %d\n", + direct_lookups,direct_searches,direct_deletes,direct_inserts,direct_splits); } -/* namecheck - take a name specification and return name length without +/* name_check() - take a name specification and return name length without the version number, an integer version number, and a wildcard flag */ -unsigned namecheck(char *str,int len,int *retlen,int *retver,int *wildflag) +unsigned name_check(char *str,int len,int *retlen,int *retver,int *wildflag) { int wildcard = 0; - char *spcbeg = str; + char *name_start = str; register int dots = 0; - register char *spc = spcbeg; - register char *spcend = spc + len; - directchecks++; - while (spc < spcend) { - register char ch = *spc++; + register char *name = name_start; + register char *name_end = name + len; + direct_checks++; + + /* Go through the specification checking for illegal characters */ + + while (name < name_end) { + register char ch = *name++; if (ch == '.') { - if ((spc - spcbeg) > 40) return SS$_BADFILENAME; - spcbeg = spc; + if ((name - name_start) > 40) return SS$_BADFILENAME; + name_start = name; if (dots++ > 1) break; } else { if (ch == ';') { @@ -75,23 +82,26 @@ unsigned namecheck(char *str,int len,int *retlen,int *retver,int *wildflag) } } } - if ((spc - spcbeg) > 40) return SS$_BADFILENAME; - *retlen = spc - str - 1; + if ((name - name_start) > 40) return SS$_BADFILENAME; + + /* Return the name length and start checking the version */ + + *retlen = name - str - 1; dots = 0; - if (spc < spcend) { - register char ch = *spc; + if (name < name_end) { + register char ch = *name; if (ch == '*') { - if (++spc < spcend) return SS$_BADFILENAME; - dots = 32768; + if (++name < name_end) return SS$_BADFILENAME; + dots = 32768; /* Wildcard representation of version! */ wildcard = 1; } else { register int sign = 1; if (ch == '-') { - spc++; + name++; sign = -1; } - while (spc < spcend) { - ch = *spc++; + while (name < name_end) { + ch = *name++; if (!isdigit(ch)) return SS$_BADFILENAME; dots = dots * 10 + (ch - '0'); } @@ -100,9 +110,6 @@ unsigned namecheck(char *str,int len,int *retlen,int *retver,int *wildflag) } *retver = dots; *wildflag = wildcard; -#ifdef DEBUG - printf("Namecheck %d %d %d\n",*retlen,*retver,*wildflag); -#endif return SS$_NORMAL; } @@ -113,219 +120,386 @@ unsigned namecheck(char *str,int len,int *retlen,int *retver,int *wildflag) #define MAT_GT 2 #define MAT_NE 3 -/* namematch - compare a name specification with a directory entry +/* name_match() - compare a name specification with a directory entry and determine if there is a match, too big, too small... */ -int namematch(char *spec,int speclen,char *entry,int entrylen) +int name_match(char *spec,int spec_len,char *dirent,int dirent_len) { - int percent = 0; - register char *spc = spec,*ent = entry; - register char *spcend = spc + speclen,*entend = ent + entrylen; - directmatches++; - /* See how much matches without wildcards... */ - if (spc < spcend && ent < entend) { - register int count = speclen; - if (entrylen < count) count = entrylen; - do { - register char sch = *spc,ech = *ent; + int percent = MAT_GT; + register char *name = spec,*entry = dirent; + register char *name_end = name + spec_len,*entry_end = entry + dirent_len; + direct_matches++; + + /* See how much name matches without wildcards... */ + + while (name < name_end && entry < entry_end) { + register char sch = *name; + if (sch != '*') { + register char ech = *entry; if (sch != ech) if (toupper(sch) != toupper(ech)) if (sch == '%') { - percent = 1; + percent = MAT_NE; } else { break; } - spc++; - ent++; - } while (--count > 0); + } else { + break; + } + name++; + entry++; } -#ifdef DEBUG - printf("Namematch %3s %d %3s %d\n",spec,speclen,entry,entrylen); -#endif + /* Mismatch - return result unless wildcard... */ - if (spc >= spcend) { - if (ent >= entend) { + + if (name >= name_end) { + if (entry >= entry_end) { return MAT_EQ; } else { - if (percent) { - return MAT_NE; - } else { - return MAT_GT; /* Entry longer than search spec */ - } + return percent; } } else { - register int offset = 0; - if (*spc != '*') { - if (percent) return MAT_NE; - if (ent < entend) - if (toupper(*ent) > toupper(*spc)) return MAT_GT; + + /* See if we can find a match with wildcards */ + + if (*name != '*') { + if (percent == MAT_NE) return MAT_NE; + if (entry < entry_end) + if (toupper(*entry) > toupper(*name)) return MAT_GT; return MAT_LT; } - /* See if we can find a match with wildcards */ - spc++; - if (spc < spcend) { - do { - if (spc >= spcend) { - if (ent >= entend) break; - spc -= offset; - ent -= offset - 1; - offset = 0; - } else { - register char sch = toupper(*spc); - if (sch == '*') { - offset = 0; - spc++; - if (spc >= spcend) break; + /* Strip out wildcard(s) - if end then we match! */ + + do { + name++; + } while (name < name_end && *name == '*'); + if (name >= name_end) return MAT_EQ; + + /* Proceed to examine the specification past the wildcard... */ + + while (name < name_end) { + register int offset = 1; + register char fch = toupper(*name++); + + /* See if can can find a match for the first character... */ + + if (fch != '%') { + while (entry < entry_end) { + if (toupper(*entry) != fch) { + entry++; } else { - if (ent < entend) { - register char ech = toupper(*ent); - if (sch == ech || sch == '%') { - offset++; - spc++; - ent++; - } else { - spc -= offset; - ent -= offset - 1; - offset = 0; - } - } else { - return MAT_NE; - } + break; } } - } while (1); + } + /* Give up if we can't find that one lousy character... */ + + if (entry >= entry_end) return MAT_NE; + entry++; + + /* See how much of the rest we can match... */ + + while (name < name_end && entry < entry_end) { + register char sch = *name,ech; + if (sch == '*') break; + if (sch != (ech = *entry)) if (toupper(sch) != toupper(ech)) + if (sch != '%') break; + name++; + entry++; + offset++; + } + + /* If matching died because of a wildcard we are OK... */ + + if (name < name_end && *name == '*') { + do { + name++; + } while (name < name_end && *name == '*'); + if (name >= name_end) return MAT_EQ; + + /* Otherwise we finished OK or we need to try again... */ + + } else { + if (name >= name_end && entry >= entry_end) return MAT_EQ; + name -= offset; + entry -= offset - 1; + } } } + + /* No more specification - match depends on remainder of entry... */ + + if (entry < entry_end) return MAT_NE; return MAT_EQ; } -unsigned freesize(char *buffer) -{ - struct dir$rec *dr = (struct dir$rec *) buffer; - do { - register char *nr = (char *) dr + dr->dir$size + 2; - if (nr >= buffer + 512) break; - dr = (struct dir$rec *) nr; - } while (1); - return (char *) dr - buffer - 2; -} +/* insert_ent() - procedure to add a directory entry at record dr entry de */ -unsigned insrec(void) +unsigned insert_ent(struct FCB * fcb,unsigned eofblk,unsigned curblk, + struct VIOC * vioc,char *buffer, + struct dir$rec * dr,struct dir$ent * de, + char *filename,unsigned filelen, + unsigned version,struct fiddef * fid) { - printf("Insert directory record\n"); - return 0; -} + register unsigned sts = 1; + register int inuse = 0; -unsigned insent(struct FCB *fcb,struct VIOC *vioc,unsigned curblk, - struct dir$rec *dr,struct dir$ent *de, - char *buffer,unsigned eofblk) -{ - printf("Insert directory entry\n"); - if (freesize(buffer) >= sizeof(struct dir$ent)) { - char *ne = (char *) de + sizeof(struct dir$ent); - memcpy(de,ne,512 - (ne - buffer)); - dr->dir$size -= sizeof(struct dir$ent); + /* Compute space required... */ + + register int addlen = sizeof(struct dir$ent); + direct_inserts++; + if (de == NULL) + addlen += (filelen + sizeof(struct dir$rec)) & ~1; + + /* Compute block space in use ... */ + + { + char invalid_dr = 1; + do { + register int sizecheck; + register struct dir$rec *nr = (struct dir$rec *) (buffer + inuse); + if (dr == nr) invalid_dr = 0; + sizecheck = VMSWORD(nr->dir$size); + if (sizecheck == 0xffff) + break; + sizecheck += 2; + inuse += sizecheck; + sizecheck -= (nr->dir$namecount + sizeof(struct dir$rec)) & ~1; + if (inuse > MAXREC || (inuse & 1) || sizecheck <= 0 || + sizecheck % sizeof(struct dir$ent) != 0) { + deaccesschunk(vioc,0,0,0); + return SS$_BADIRECTORY; + } + } while (1); + + if (invalid_dr) { + printf("BUGCHECK invalid dr\n"); + exit(0); + } + if (de != NULL) { + if (VMSWORD(dr->dir$size) > MAXREC || (char *) de < dr->dir$name + + dr->dir$namecount || (char *) de > (char *) dr + VMSWORD(dr->dir$size) + 2) { + printf("BUGCHECK invalid de\n"); + exit(0); + } + } } - return 0; + + /* If not enough space free extend the directory... */ + + if (addlen > MAXREC - inuse) { + register struct dir$rec *nr; + unsigned keep_new = 0; + char *newbuf; + struct VIOC *newvioc; + unsigned newblk = eofblk + 1; + direct_splits++; + printf("Splitting record... %d %d\n",dr,de); + if (newblk > fcb->hiblock) { + printf("I can't extend a directory yet!!\n"); + exit(0); + } + fcb->highwater = 0; + sts = accesschunk(fcb,newblk,&newvioc,&newbuf,NULL,1); + if (sts & 1) { + while (newblk > curblk + 1) { + char *frombuf; + struct VIOC *fromvioc; + sts = accesschunk(fcb,newblk - 1,&fromvioc,&frombuf,NULL,1); + if ((sts & 1) == 0) break; + memcpy(newbuf,frombuf,BLOCKSIZE);; + sts = deaccesschunk(newvioc,newblk,1,1); + newvioc = fromvioc; + newbuf = frombuf; + newblk--; + if ((sts & 1) == 0) break; + } + } else { + newvioc = NULL; + } + if ((sts & 1) == 0) { + if (newvioc != NULL) deaccesschunk(newvioc,0,0,0); + deaccesschunk(vioc,0,0,0); + return sts; + } + memset(newbuf,0,BLOCKSIZE); + eofblk++; + fcb->head->fh2$w_recattr.fat$l_efblk = VMSWORD(eofblk + 1); + + /* First find where the next record is... */ + + nr = dr; + if (VMSWORD(nr->dir$size) <= MAXREC) + nr = (struct dir$rec *) ((char *) nr + VMSWORD(nr->dir$size) + 2); + + /* Can we split between records? */ + + if (de == NULL || (char *) dr != buffer || VMSWORD(nr->dir$size) <= MAXREC) { + register struct dir$rec *sp = dr; + if ((char *) dr == buffer && de != NULL) sp = nr; + memcpy(newbuf,sp,((buffer + BLOCKSIZE) - (char *) sp)); + memset(sp,0,((buffer + BLOCKSIZE) - (char *) sp)); + sp->dir$size = VMSWORD(0xffff); + if (sp == dr && (de != NULL || (char *) sp >= buffer + MAXREC - addlen)) { + if (de != NULL) + de = (struct dir$ent *) + (newbuf + ((char *) de - (char *) sp)); + dr = (struct dir$rec *) (newbuf + ((char *) dr - (char *) sp)); + keep_new = 1; + } + /* OK, we have to split the record then.. */ + + } else { + register unsigned reclen = (dr->dir$namecount + + sizeof(struct dir$rec)) & ~1; + register struct dir$rec *nbr = (struct dir$rec *) newbuf; + printf("Super split %d %d\n",dr,de); + memcpy(newbuf,buffer,reclen); + memcpy(newbuf + reclen,de,((char *) nr - (char *) de) + 2); + nbr->dir$size = VMSWORD(reclen + ((char *) nr - (char *) de) - 2); + + memset((char *) de + 2,0,((char *) nr - (char *) de)); + ((struct dir$rec *) de)->dir$size = VMSWORD(0xffff); + dr->dir$size = VMSWORD(((char *) de - (char *) dr) - 2); + if ((char *) de >= (char *) nr) { + dr = (struct dir$rec *) newbuf; + de = (struct dir$ent *) (newbuf + reclen); + keep_new = 1; + } + } + + /* Need to decide which buffer we are going to keep (to write to) */ + + if (keep_new) { + sts = deaccesschunk(vioc,curblk,1,1); + curblk = newblk; + vioc = newvioc; + buffer = newbuf; + } else { + sts = deaccesschunk(newvioc,newblk,1,1); + } + if ((sts & 1) == 0) printf("Bad status %d\n",sts); + } + /* After that we can just add the record or entry as appropriate... */ + + if (de == NULL) { + memmove((char *) dr + addlen,dr,BLOCKSIZE - (((char *) dr + addlen) - buffer)); + dr->dir$size = VMSWORD(addlen - 2); + dr->dir$verlimit = 0; + dr->dir$flags = 0; + dr->dir$namecount = filelen; + memcpy(dr->dir$name,filename,filelen); + de = (struct dir$ent *) ((char *) dr + (addlen - sizeof(struct dir$ent))); + } else { + dr->dir$size = VMSWORD(VMSWORD(dr->dir$size) + addlen); + memmove((char *) de + addlen,de,BLOCKSIZE - (((char *) de + addlen) - buffer)); + } + + /* Write the entry values are we are done! */ + + de->dir$version = VMSWORD(version); + fid_copy(&de->dir$fid,fid,0); + return deaccesschunk(vioc,curblk,1,1); } -/* delent - delete a directory entry */ -unsigned delent(struct FCB *fcb,struct VIOC *vioc,unsigned curblk, - struct dir$rec *dr,struct dir$ent *de, - char *buffer,unsigned modmask,unsigned eofblk) +/* delete_ent() - delete a directory entry */ + +unsigned delete_ent(struct FCB * fcb,struct VIOC * vioc,unsigned curblk, + struct dir$rec * dr,struct dir$ent * de, + char *buffer,unsigned eofblk) { unsigned sts = 1; unsigned ent; - directdels++; - ent = (dr->dir$size - sizeof(struct dir$rec) + direct_deletes++; + ent = (VMSWORD(dr->dir$size) - sizeof(struct dir$rec) - dr->dir$namecount + 3) / sizeof(struct dir$ent); - printf("DELENT ent = %d %d %d\n",ent,curblk,eofblk); if (ent > 1) { char *ne = (char *) de + sizeof(struct dir$ent); - memcpy(de,ne,512 - (ne - buffer)); - dr->dir$size -= sizeof(struct dir$ent); + memcpy(de,ne,BLOCKSIZE - (ne - buffer)); + dr->dir$size = VMSWORD(VMSWORD(dr->dir$size) - sizeof(struct dir$ent)); } else { - char *nr = (char *) dr + dr->dir$size + 2; + char *nr = (char *) dr + VMSWORD(dr->dir$size) + 2; if (eofblk == 1 || (char *) dr > buffer || - (nr <= buffer + 510 && (unsigned short) *nr < 512)) { - memcpy(dr,nr,512 - (nr - buffer)); + (nr <= buffer + MAXREC && (unsigned short) *nr < BLOCKSIZE)) { + memcpy(dr,nr,BLOCKSIZE - (nr - buffer)); } else { - printf("DELENT shrinking file size %d %d\n",curblk,eofblk); while (curblk < eofblk) { char *nxtbuffer; struct VIOC *nxtvioc; - unsigned nxtmodmask; - sts = accesschunk(fcb,++curblk,&nxtvioc,&nxtbuffer,NULL,1,&nxtmodmask); + sts = accesschunk(fcb,curblk + 1,&nxtvioc,&nxtbuffer,NULL,1); if ((sts & 1) == 0) break; - memcpy(buffer,nxtbuffer,512); - sts = deaccesschunk(vioc,modmask,1); + memcpy(buffer,nxtbuffer,BLOCKSIZE); + sts = deaccesschunk(vioc,curblk++,1,1); if ((sts & 1) == 0) break; buffer = nxtbuffer; vioc = nxtvioc; - modmask = nxtmodmask; } if (sts & 1) { - fcb->head->fh2$w_recattr.fat$l_efblk[0] = eofblk >> 16; - fcb->head->fh2$w_recattr.fat$l_efblk[1] = (eofblk & 0xffff); + fcb->head->fh2$w_recattr.fat$l_efblk = VMSSWAP(eofblk); eofblk--; } } } { - unsigned retsts = deaccesschunk(vioc,modmask,1); + unsigned retsts = deaccesschunk(vioc,curblk,1,1); if (sts & 1) sts = retsts; return sts; } } -/* retent - return information about a directory entry */ +/* return_ent() - return information about a directory entry */ -unsigned retent(struct FCB *fcb,struct VIOC *vioc,unsigned curblk, - struct dir$rec *dr,struct dir$ent *de,struct fibdef *fib, - unsigned short *reslen,struct dsc$descriptor *resdsc, - int wildcard) +unsigned return_ent(struct FCB * fcb,struct VIOC * vioc,unsigned curblk, + struct dir$rec * dr,struct dir$ent * de,struct fibdef * fib, + unsigned short *reslen,struct dsc_descriptor * resdsc, + int wildcard) { register int scale = 10; - register int version = de->dir$version; + register int version = VMSWORD(de->dir$version); register int length = dr->dir$namecount; - register char *ptr = resdsc->dsc$a_pointer; + register char *ptr = resdsc->dsc_a_pointer; + register int outlen = resdsc->dsc_w_length; + if (length > outlen) length = outlen; memcpy(ptr,dr->dir$name,length); while (version >= scale) scale *= 10; - ptr += length++; - *ptr++ = ';'; - do { - scale /= 10; - *ptr++ = version / scale + '0'; - version %= scale; + ptr += length; + if (length < outlen) { + *ptr++ = ';'; length++; - } while (scale > 1); + do { + if (length >= outlen) break; + scale /= 10; + *ptr++ = version / scale + '0'; + version %= scale; + length++; + } while (scale > 1); + } *reslen = length; - memcpy(&fib->fib$w_fid_num,&de->dir$fid,sizeof(struct fiddef)); + fid_copy((struct fiddef *)&fib->fib$w_fid_num,&de->dir$fid,0); if (fib->fib$b_fid_rvn == 0) fib->fib$b_fid_rvn = fcb->rvn; if (wildcard || (fib->fib$w_nmctl & FIB$M_WILD)) { fib->fib$l_wcc = curblk; } else { fib->fib$l_wcc = 0; } - return deaccesschunk(vioc,0,1); + return deaccesschunk(vioc,0,0,1); } -/* searchent - search for a directory entry */ +/* search_ent() - search for a directory entry */ -unsigned searchent(struct FCB * fcb, - struct dsc$descriptor * fibdsc,struct dsc$descriptor * filedsc, - unsigned short *reslen,struct dsc$descriptor * resdsc,unsigned eofblk,unsigned action) +unsigned search_ent(struct FCB * fcb, + struct dsc_descriptor * fibdsc,struct dsc_descriptor * filedsc, + unsigned short *reslen,struct dsc_descriptor * resdsc,unsigned eofblk,unsigned action) { register unsigned sts,curblk; struct VIOC *vioc = NULL; - unsigned modmask; char *searchspec,*buffer; int searchlen,version,wildcard,wcc_flag; - struct fibdef *fib = (struct fibdef *) fibdsc->dsc$a_pointer; - directlookups++; + struct fibdef *fib = (struct fibdef *) fibdsc->dsc_a_pointer; + direct_lookups++; /* 1) Generate start block (wcc gives start point) 2) Search for start @@ -333,14 +507,14 @@ unsigned searchent(struct FCB * fcb, curblk = fib->fib$l_wcc; if (curblk != 0) { - searchspec = resdsc->dsc$a_pointer; - sts = namecheck(searchspec,*reslen,&searchlen,&version,&wildcard); - if (action || wildcard) return SS$_BADFILENAME; + searchspec = resdsc->dsc_a_pointer; + sts = name_check(searchspec,*reslen,&searchlen,&version,&wildcard); + if (action || wildcard) sts = SS$_BADFILENAME; wcc_flag = 1; } else { - searchspec = filedsc->dsc$a_pointer; - sts = namecheck(searchspec,filedsc->dsc$w_length,&searchlen,&version,&wildcard); - if ((action && wildcard) || (action > 1 && version < 0)) return SS$_BADFILENAME; + searchspec = filedsc->dsc_a_pointer; + sts = name_check(searchspec,filedsc->dsc_w_length,&searchlen,&version,&wildcard); + if ((action && wildcard) || (action > 1 && version < 0)) sts = SS$_BADFILENAME; wcc_flag = 0; } if ((sts & 1) == 0) return sts; @@ -357,35 +531,30 @@ unsigned searchent(struct FCB * fcb, register int cmp; register unsigned newblk; register struct dir$rec *dr; - directsearches++; - sts = accesschunk(fcb,curblk,&vioc,&buffer,NULL,action ? 1 : 0,&modmask); + direct_searches++; + sts = accesschunk(fcb,curblk,&vioc,&buffer,NULL,action ? 1 : 0); if ((sts & 1) == 0) return sts; dr = (struct dir$rec *) buffer; - if (dr->dir$size > 510) { + if (VMSWORD(dr->dir$size) > MAXREC) { cmp = MAT_GT; } else { - cmp = namematch(searchspec,searchlen,dr->dir$name,dr->dir$namecount); + cmp = name_match(searchspec,searchlen,dr->dir$name,dr->dir$namecount); if (cmp == MAT_EQ) { if (wildcard || version < 1 || version > 32767) { cmp = MAT_NE; /* no match - want to find start */ } else { register struct dir$ent *de = (struct dir$ent *) (dr->dir$name + ((dr->dir$namecount + 1) & ~1)); - if (de->dir$version < version) { + if (VMSWORD(de->dir$version) < version) { cmp = MAT_GT; /* too far... */ } else { - if (de->dir$version > version) { + if (VMSWORD(de->dir$version) > version) { cmp = MAT_LT; /* further ahead... */ } } } } } -#ifdef DEBUG - printf("Direct %6.6s %d %6.6s %d (%d<%d<%d)-> %d\n", - searchspec,searchlen,dr->dir$name,dr->dir$namecount, - loblk,curblk,hiblk,cmp); -#endif switch (cmp) { case MAT_LT: if (curblk == fib->fib$l_wcc) { @@ -404,7 +573,7 @@ unsigned searchent(struct FCB * fcb, newblk = hiblk = loblk = curblk; } if (newblk != curblk) { - sts = deaccesschunk(vioc,0,1); + sts = deaccesschunk(vioc,0,0,1); if ((sts & 1) == 0) return sts; vioc = NULL; curblk = newblk; @@ -415,99 +584,154 @@ unsigned searchent(struct FCB * fcb, /* Now to read sequentially to find entry... */ - while ((sts & 1) && curblk <= eofblk) { - register struct dir$rec *dr; - if (vioc == NULL) { - sts = accesschunk(fcb,curblk,&vioc,&buffer,NULL,action ? 1 : 0,&modmask); - if ((sts & 1) == 0) return sts; - } - dr = (struct dir$rec *) buffer; - do { - register int cmp; - register char *nr = (char *) dr + dr->dir$size + 2; - if (nr >= buffer + 512) break; - cmp = namematch(searchspec,searchlen,dr->dir$name,dr->dir$namecount); -#ifdef DEBUF - printf("Direct %6.6s %d %6.6s %d -> %d\n", - searchspec,searchlen,dr->dir$name,dr->dir$namecount,cmp); -#endif - if (cmp == MAT_GT) { - if (wcc_flag) { + { + char last_name[80]; + unsigned last_len = 0; + register int relver = 0; + while ((sts & 1) && curblk <= eofblk) { + register struct dir$rec *dr; + register int cmp = MAT_LT; + + /* Access a directory block. Reset relative version if it starts + with a record we haven't seen before... */ + + if (vioc == NULL) { + sts = accesschunk(fcb,curblk,&vioc,&buffer,NULL,action ? 1 : 0); + if ((sts & 1) == 0) return sts; + } + dr = (struct dir$rec *) buffer; + if (last_len != dr->dir$namecount) { + relver = 0; + } else { + if (name_match(last_name,last_len,dr->dir$name,last_len) != MAT_EQ) { + relver = 0; + } + } + + /* Now loop through the records seeing which match our spec... */ + + do { + register char *nr = (char *) dr + VMSWORD(dr->dir$size) + 2; + if (nr >= buffer + BLOCKSIZE) break; + if (dr->dir$name + dr->dir$namecount >= nr) break; + cmp = name_match(searchspec,searchlen,dr->dir$name,dr->dir$namecount); + if (cmp == MAT_GT && wcc_flag) { wcc_flag = 0; - searchspec = filedsc->dsc$a_pointer; - sts = namecheck(searchspec,filedsc->dsc$w_length,&searchlen,&version,&wildcard); + searchspec = filedsc->dsc_a_pointer; + sts = name_check(searchspec,filedsc->dsc_w_length,&searchlen,&version,&wildcard); if ((sts & 1) == 0) break; } else { - curblk = eofblk; /* give up */ - break; - } - } else { - if (cmp == MAT_EQ) { - register int relver = 0; - register struct dir$ent *de = (struct dir$ent *) (dr->dir$name + - ((dr->dir$namecount + 1) & ~1)); - while ((char *) de < nr) { - if (version >= de->dir$version || (version < 1 && version >= relver)) { - cmp = MAT_GT; - if (version > 32767 || version == relver || - version == de->dir$version) cmp = MAT_EQ; - if (wcc_flag) { - wcc_flag = 0; - searchspec = filedsc->dsc$a_pointer; - sts = namecheck(searchspec,filedsc->dsc$w_length,&searchlen,&version,&wildcard); - if ((sts & 1) == 0) break; - if (namematch(searchspec,searchlen,dr->dir$name, - dr->dir$namecount) != MAT_EQ) { - break; - } - if (cmp == MAT_EQ) { - cmp = MAT_LT; - } else { - cmp = MAT_LT; - if (version >= de->dir$version || (version < 1 && version >= relver)) { - cmp = MAT_GT; - if (version > 32767 || version == relver || - version == de->dir$version) cmp = MAT_EQ; - } - } - } - if (cmp == MAT_EQ) { - switch (action) { - case 0: - return -retent(fcb,vioc,curblk,dr,de,fib,reslen,resdsc,wildcard); - case 1: - return -delent(fcb,vioc,curblk,dr,de,buffer,modmask,eofblk); - default: - sts = SS$_DUPFILENAME; - de = (struct dir$ent *) nr; - } - } else { - if (cmp == MAT_GT) break; + if (cmp == MAT_EQ) { + register struct dir$ent *de = (struct dir$ent *) (dr->dir$name + + ((dr->dir$namecount + 1) & ~1)); + if (version == 0 && action == 2) { + version = VMSWORD(de->dir$version) + 1; + if (version > 32767) { + sts = SS$_BADFILENAME; + break; + } + } + /* Look at each directory entry to see + if it is what we want... */ + + if ((char *) dr != buffer) relver = 0; + cmp = MAT_LT; + while ((char *) de < nr) { + if ((version < 1) ? (relver > version) : (version < VMSWORD(de->dir$version))) { + relver--; + de++; + } else { + if (version > 32767 || version == relver || version == VMSWORD(de->dir$version)) { + cmp = MAT_EQ; + } else { + cmp = MAT_GT; + } + if (wcc_flag == 0) { + break; + } else { + wcc_flag = 0; + searchspec = filedsc->dsc_a_pointer; + sts = name_check(searchspec,filedsc->dsc_w_length,&searchlen,&version,&wildcard); + if ((sts & 1) == 0) break; + if (name_match(searchspec,searchlen,dr->dir$name, + dr->dir$namecount) != MAT_EQ) { + cmp = MAT_NE; + break; + } + if (version < 0) { + relver = -32768; + cmp = MAT_GT; + break; + } + if (cmp == MAT_EQ) { + relver--; + de++; + } + cmp = MAT_LT; + } + } + } + if ((sts & 1) == 0) break; + + /* Decide what to do with the entry we have found... */ + + if (cmp == MAT_EQ) { + switch (action) { + case 0: + return return_ent(fcb,vioc,curblk,dr,de,fib,reslen,resdsc,wildcard); + case 1: + return delete_ent(fcb,vioc,curblk,dr,de,buffer,eofblk); + default: + sts = SS$_DUPFILENAME; + break; + } + } else { + if (cmp != MAT_NE && action == 2) { + return insert_ent(fcb,eofblk,curblk,vioc,buffer,dr,de, + searchspec,searchlen,version,(struct fiddef *) & fib->fib$w_fid_num); } } - relver--; - de++; } - if ((sts & 1) == 0) break; - if (action == 2) { - return insent(fcb,vioc,curblk,dr,de,buffer,eofblk); + /* Finish unless we expect more... */ + + if (cmp == MAT_GT && wildcard == 0) break; + + /* If this is the last record in the block store the name + so that if it continues into the next block we can get + the relative version right! Sigh! */ + + if (VMSWORD(((struct dir$rec *) nr)->dir$size) > MAXREC) { + last_len = dr->dir$namecount; + if (last_len > sizeof(last_name)) last_len = sizeof(last_name); + memcpy(last_name,dr->dir$name,last_len); + dr = (struct dir$rec *) nr; + break; } + dr = (struct dir$rec *) nr; } - dr = (struct dir$rec *) nr; + } while (1); /* dr records within block */ + + /* We release the buffer ready to get the next one - unless it is the + last one in which case we can't defer an insert any longer!! */ + + if ((sts & 1) == 0 || action != 2 || (cmp != MAT_GT && curblk < eofblk)) { + register unsigned dests = deaccesschunk(vioc,0,0,1); + if ((dests & 1) == 0) { + sts = dests; + break; + } + vioc = NULL; + curblk++; + } else { + if (version == 0) version = 1; + return insert_ent(fcb,eofblk,curblk,vioc,buffer,dr,NULL, + searchspec,searchlen,version,(struct fiddef *) & fib->fib$w_fid_num); } - } while (1); - { - register unsigned dests = deaccesschunk(vioc,0,1); - vioc = NULL; - if (sts & 1) sts = dests; - } - curblk++; - } - if (action == 2) { - return insrec(); + } /* curblk blocks within file */ } + + /* We achieved nothing! Report the failure... */ + if (sts & 1) { fib->fib$l_wcc = 0; if (wcc_flag || wildcard) { @@ -520,24 +744,24 @@ delent(fcb,vioc,curblk,dr,de,buffer,modmask,eofblk); } -/* direct - this routine handles all directory manipulations:- +/* direct() - this routine handles all directory manipulations:- action 0 - find directory entry 1 - delete entry 2 - create an entry */ -unsigned direct(struct VCB *vcb,struct dsc$descriptor * fibdsc, - struct dsc$descriptor *filedsc,unsigned short *reslen, - struct dsc$descriptor *resdsc,unsigned action) +unsigned direct(struct VCB * vcb,struct dsc_descriptor * fibdsc, + struct dsc_descriptor * filedsc,unsigned short *reslen, + struct dsc_descriptor * resdsc,unsigned action) { struct FCB *fcb; register unsigned sts,eofblk; - register struct fibdef *fib = (struct fibdef *) fibdsc->dsc$a_pointer; + register struct fibdef *fib = (struct fibdef *) fibdsc->dsc_a_pointer; sts = accessfile(vcb,(struct fiddef *) & fib->fib$w_did_num,&fcb,action); if (sts & 1) { - if (fcb->head->fh2$l_filechar & FH2$M_DIRECTORY) { - eofblk = swapw(fcb->head->fh2$w_recattr.fat$l_efblk); - if (fcb->head->fh2$w_recattr.fat$w_ffbyte == 0) --eofblk; - sts = searchent(fcb,fibdsc,filedsc,reslen,resdsc,eofblk,action); + if (VMSLONG(fcb->head->fh2$l_filechar) & FH2$M_DIRECTORY) { + eofblk = VMSSWAP(fcb->head->fh2$w_recattr.fat$l_efblk); + if (VMSWORD(fcb->head->fh2$w_recattr.fat$w_ffbyte) == 0) --eofblk; + sts = search_ent(fcb,fibdsc,filedsc,reslen,resdsc,eofblk,action); } else { sts = SS$_BADIRECTORY; } diff --git a/extracters/ods2/direct.h b/extracters/ods2/direct.h index 17f5717..480527a 100644 --- a/extracters/ods2/direct.h +++ b/extracters/ods2/direct.h @@ -1,4 +1,4 @@ -/* Direct.h v1.2 Definitions for directory access routines */ +/* Direct.h v1.3 Definitions for directory access routines */ /* This is part of ODS2 written by Paul Nankervis, @@ -13,19 +13,19 @@ struct dir$rec { - u_word dir$size; - u_word dir$verlimit; - u_byte dir$flags; - u_byte dir$namecount; + vmsword dir$size; + vmsword dir$verlimit; + vmsbyte dir$flags; + vmsbyte dir$namecount; char dir$name[1]; }; struct dir$ent { - u_word dir$version; + vmsword dir$version; struct fiddef dir$fid; }; -unsigned direct(struct VCB *vcb,struct dsc$descriptor * fibdsc, - struct dsc$descriptor *filedsc,unsigned short *reslen, - struct dsc$descriptor *resdsc,unsigned action); +unsigned direct(struct VCB *vcb,struct dsc_descriptor *fibdsc, + struct dsc_descriptor *filedsc,unsigned short *reslen, + struct dsc_descriptor *resdsc,unsigned action); diff --git a/extracters/ods2/fibdef.h b/extracters/ods2/fibdef.h index 40670e4..7bf84f5 100644 --- a/extracters/ods2/fibdef.h +++ b/extracters/ods2/fibdef.h @@ -1,4 +1,4 @@ -/* Fibdef.h v1.2 Definition of 'struct fibdef' */ +/* Fibdef.h v1.3 Definition of 'struct fibdef' */ /* This is part of ODS2 written by Paul Nankervis, @@ -11,11 +11,7 @@ */ -#if defined(VMS) && !defined(__GNUC__) - -#include - -#else +#ifndef FIM$M_WILD #define FIB$M_WILD 0x100 diff --git a/extracters/ods2/header.h b/extracters/ods2/header.h new file mode 100644 index 0000000..9b0c5bd --- /dev/null +++ b/extracters/ods2/header.h @@ -0,0 +1,189 @@ +/* Header.h v1.0 Definitions for ODS2 file headers */ + +/* Small macro to swap words in a longword */ + +#define swapw(w) (w[0]<<16 | w[1]) + +/* File characteristic definitions */ + +#define FCH$M_NOBACKUP 0x2 +#define FCH$M_CONTIGB 0x20 +#define FCH$M_LOCKED 0x40 +#define FCH$M_CONTIG 0x80 +#define FCH$M_DIRECTORY 0x2000 +#define FCH$M_MARKDEL 0x8000 +#define FCH$M_ERASE 0x20000 + +/* File and record attribute definitions */ + +#define FAT$C_FIXED 0x1 +#define FAT$C_VARIABLE 0x2 +#define FAT$C_VFC 0x3 +#define FAT$C_UNDEFINED 0x0 +#define FAT$C_STREAM 0x4 +#define FAT$C_STREAMLF 0x5 +#define FAT$C_STREAMCR 0x6 + +#define FAT$C_DIRECT 0x3 +#define FAT$C_INDEXED 0x2 +#define FAT$C_RELATIVE 0x1 +#define FAT$C_SEQUENTIAL 0x0 + +#define FAT$M_FORTRANCC 0x1 +#define FAT$M_IMPLIEDCC 0x2 +#define FAT$M_PRINTCC 0x4 +#define FAT$M_NOSPAN 0x8 +#define FAT$M_MSBRCW 0x10 + +/* Type definitions for basic data types */ + +typedef unsigned char u_byte; +typedef unsigned short u_word; +typedef unsigned int u_long; + +/* Structure of time */ + +struct TIME { + unsigned char time[8]; +}; + +/* Definition of a UIC */ + +struct UIC { + u_word uic$w_mem; + u_word uic$w_grp; +}; + +/* Definition for a FID */ + +struct fiddef { + u_word fid$w_num; + u_word fid$w_seq; + u_byte fid$b_rvn; + u_byte fid$b_nmx; +}; + +/* RMS record definition */ + +struct RECATTR { + u_byte fat$b_rtype; + u_byte fat$b_rattrib; + u_word fat$w_rsize; + u_word fat$l_hiblk[2]; + u_word fat$l_efblk[2]; + u_word fat$w_ffbyte; + u_byte fat$b_bktsize; + u_byte fat$b_vfcsize; + u_word fat$w_maxrec; + u_word fat$w_defext; + u_word fat$w_gbc; + u_byte fat$_UU0[8]; + u_word fat$w_versions; +}; + +/* Layout of the volume home block... */ + +struct HOME { + u_long hm2$l_homelbn; + u_long hm2$l_alhomelbn; + u_long hm2$l_altidxlbn; + u_word hm2$w_struclev; + u_word hm2$w_cluster; + u_word hm2$w_homevbn; + u_word hm2$w_alhomevbn; + u_word hm2$w_altidxvbn; + u_word hm2$w_ibmapvbn; + u_long hm2$l_ibmaplbn; + u_long hm2$l_maxfiles; + u_word hm2$w_ibmapsize; + u_word hm2$w_resfiles; + u_word hm2$w_devtype; + u_word hm2$w_rvn; + u_word hm2$w_setcount; + u_word hm2$w_volchar; + struct UIC hm2$w_volowner; + u_long hm2$l_reserved1; + u_word hm2$w_protect; + u_word hm2$w_fileprot; + u_word hm2$w_reserved2; + u_word hm2$w_checksum1; + struct TIME hm2$q_credate; + u_byte hm2$b_window; + u_byte hm2$b_lru_lim; + u_word hm2$w_extend; + struct TIME hm2$q_retainmin; + struct TIME hm2$q_retainmax; + struct TIME hm2$q_revdate; + u_byte hm2$r_min_class[20]; + u_byte hm2$r_max_class[20]; + u_byte hm2$t_reserved3[320]; + u_long hm2$l_serialnum; + char hm2$t_strucname[12]; + char hm2$t_volname[12]; + char hm2$t_ownername[12]; + char hm2$t_format[12]; + u_word hm2$w_reserved4; + u_word hm2$w_checksum2; +}; + +/* Structure of the header identification area */ + +struct IDENT { + char fi2$t_filename[20]; + u_word fi2$w_revision; + struct TIME fi2$q_credate; + struct TIME fi2$q_revdate; + struct TIME fi2$q_expdate; + struct TIME fi2$q_bakdate; + char fi2$t_filenamext[66]; +}; + +/* File header layout */ + +struct HEAD { + u_byte fh2$b_idoffset; + u_byte fh2$b_mpoffset; + u_byte fh2$b_acoffset; + u_byte fh2$b_rsoffset; + u_word fh2$w_seg_num; + u_word fh2$w_struclev; + struct fiddef fh2$w_fid; + struct fiddef fh2$w_ext_fid; + struct RECATTR fh2$w_recattr; + u_long fh2$l_filechar; + u_word fh2$w_reserved1; + u_byte fh2$b_map_inuse; + u_byte fh2$b_acc_mode; + struct UIC fh2$l_fileowner; + u_word fh2$w_fileprot; + struct fiddef fh2$w_backlink; + u_byte fh2$b_journal; + u_byte fh2$b_ru_active; + u_word fh2$w_reserved2; + u_long fh2$l_highwater; + u_byte fh2$b_reserved3[8]; + u_byte fh2$r_class_prot[20]; + u_byte fh2$r_restofit[402]; + u_word fh2$w_checksum; +}; + +/* Storage control block layout */ + +struct SCB { + u_word scb$w_struclev; + u_word scb$w_cluster; + u_long scb$l_volsize; + u_long scb$l_blksize; + u_long scb$l_sectors; + u_long scb$l_tracks; + u_long scb$l_cylinders; + u_long scb$l_status; + u_long scb$l_status2; + u_word scb$w_writecnt; + char scb$t_volockname[12]; + struct TIME scb$q_mounttime; + u_word scb$w_backrev; + u_long scb$q_genernum[2]; + char scb$b_reserved[446]; + u_word scb$w_checksum; +}; diff --git a/extracters/ods2/makefile.nt b/extracters/ods2/makefile.nt new file mode 100644 index 0000000..6120065 --- /dev/null +++ b/extracters/ods2/makefile.nt @@ -0,0 +1,53 @@ + +CCFLAGS = "-Oxs" + +DEFS = "-DVERSION=\"v1.3\"" + +all : ods2 + +OBJS = ods2.obj \ +rms.obj \ +direct.obj \ +update.obj \ +access.obj \ +device.obj \ +phynt.obj \ +cache.obj \ +vmstime.obj + +ods2 : $(OBJS) wnaspi32.lib + $(CC) $(CCFLAGS) -oods2 $(OBJS) wnaspi32.lib + +vmstime.obj : vmstime.c vmstime.h + $(CC) -c $(CCFLAGS) $(DEFS) vmstime.c + +cache.obj : cache.c cache.h ssdef.h + $(CC) -c $(CCFLAGS) $(DEFS) cache.c + +phynt.obj : phynt.c phyio.h ssdef.h + $(CC) -c $(CCFLAGS) $(DEFS) phynt.c + +device.obj : device.c ssdef.h access.h phyio.h + $(CC) -c $(CCFLAGS) $(DEFS) device.c + +access.obj : access.c ssdef.h access.h phyio.h + $(CC) -c $(CCFLAGS) $(DEFS) access.c + +update.obj : update.c ssdef.h access.h + $(CC) -c $(CCFLAGS) $(DEFS) update.c + +direct.obj : direct.c direct.h access.h fibdef.h descrip.h ssdef.h + $(CC) -c $(CCFLAGS) $(DEFS) direct.c + +rms.obj : rms.c rms.h direct.h access.h fibdef.h descrip.h ssdef.h + $(CC) -c $(CCFLAGS) $(DEFS) rms.c + +ods2.obj : ods2.c ssdef.h descrip.h access.h rms.h + $(CC) -c $(CCFLAGS) $(DEFS) ods2.c + +wnaspi32.lib : wnaspi32.def + LIB /DEF:WNASPI32.DEF /MACHINE:IX86 + +clean: + del *.obj + del *.exe diff --git a/extracters/ods2/makefile.solaris b/extracters/ods2/makefile.solaris new file mode 100644 index 0000000..535f3aa --- /dev/null +++ b/extracters/ods2/makefile.solaris @@ -0,0 +1,36 @@ + +CCFLAGS = "-g" + +DEFS = "-DVERSION=\"v1.3\"" + +all : ods2 + +ods2 : ods2.o rms.o direct.o update.o access.o device.o phyunix.o cache.o vmstime.o + gcc $(CCFLAGS) -oods2 ods2.o rms.o direct.o update.o access.o device.o phyunix.o cache.o vmstime.o + +vmstime.o : vmstime.c vmstime.h + gcc -c $(CCFLAGS) $(DEFS) vmstime.c + +cache.o : cache.c cache.h ssdef.h + gcc -c $(CCFLAGS) $(DEFS) cache.c + +phyunix.o : phyunix.c phyio.h ssdef.h + gcc -c $(CCFLAGS) $(DEFS) phyunix.c + +device.o : device.c ssdef.h access.h phyio.h + gcc -c $(CCFLAGS) $(DEFS) device.c + +access.o : access.c ssdef.h access.h phyio.h + gcc -c $(CCFLAGS) $(DEFS) access.c + +update.o : update.c ssdef.h access.h + gcc -c $(CCFLAGS) $(DEFS) update.c + +direct.o : direct.c direct.h access.h fibdef.h descrip.h ssdef.h + gcc -c $(CCFLAGS) $(DEFS) direct.c + +rms.o : rms.c rms.h direct.h access.h fibdef.h descrip.h ssdef.h + gcc -c $(CCFLAGS) $(DEFS) rms.c + +ods2.o : ods2.c ssdef.h descrip.h access.h rms.h + gcc -c $(CCFLAGS) $(DEFS) ods2.c diff --git a/extracters/ods2/makefile.tru64 b/extracters/ods2/makefile.tru64 new file mode 100644 index 0000000..e6305db --- /dev/null +++ b/extracters/ods2/makefile.tru64 @@ -0,0 +1,34 @@ + +CCFLAGS = "-g" + +all : ods2 + +ods2 : ods2.o rms.o direct.o update.o access.o device.o phyunix.o cache.o vmstime.o + cc $(CCFLAGS) -o ods2 ods2.o rms.o direct.o update.o access.o device.o phyunix.o cache.o vmstime.o + +vmstime.o : vmstime.c vmstime.h + cc -c $(CCFLAGS) $(DEFS) vmstime.c + +cache.o : cache.c cache.h ssdef.h + cc -c $(CCFLAGS) $(DEFS) cache.c + +phyunix.o : phyunix.c phyio.h ssdef.h + cc -c $(CCFLAGS) $(DEFS) phyunix.c + +device.o : device.c ssdef.h access.h phyio.h + cc -c $(CCFLAGS) $(DEFS) device.c + +access.o : access.c ssdef.h access.h phyio.h + cc -c $(CCFLAGS) $(DEFS) access.c + +update.o : update.c ssdef.h access.h + cc -c $(CCFLAGS) $(DEFS) update.c + +direct.o : direct.c direct.h access.h fibdef.h descrip.h ssdef.h + cc -c $(CCFLAGS) $(DEFS) direct.c + +rms.o : rms.c rms.h direct.h access.h fibdef.h descrip.h ssdef.h + cc -c $(CCFLAGS) $(DEFS) rms.c + +ods2.o : ods2.c ssdef.h descrip.h access.h rms.h + cc -c $(CCFLAGS) $(DEFS) ods2.c diff --git a/extracters/ods2/makefile.unix b/extracters/ods2/makefile.unix new file mode 100644 index 0000000..6a3c0d8 --- /dev/null +++ b/extracters/ods2/makefile.unix @@ -0,0 +1,36 @@ + +CCFLAGS = "-g" + +DEFS = "-DVERSION=\"v1.3\"" + +all : ods2 + +ods2 : ods2.o rms.o direct.o update.o access.o device.o phyunix.o cache.o vmstime.o + cc $(CCFLAGS) -oods2 ods2.o rms.o direct.o update.o access.o device.o phyunix.o cache.o vmstime.o + +vmstime.o : vmstime.c vmstime.h + cc -c $(CCFLAGS) $(DEFS) vmstime.c + +cache.o : cache.c cache.h ssdef.h + cc -c $(CCFLAGS) $(DEFS) cache.c + +phyunix.o : phyunix.c phyio.h ssdef.h + cc -c $(CCFLAGS) $(DEFS) phyunix.c + +device.o : device.c ssdef.h access.h phyio.h + cc -c $(CCFLAGS) $(DEFS) device.c + +access.o : access.c ssdef.h access.h phyio.h + cc -c $(CCFLAGS) $(DEFS) access.c + +update.o : update.c ssdef.h access.h + cc -c $(CCFLAGS) $(DEFS) update.c + +direct.o : direct.c direct.h access.h fibdef.h descrip.h ssdef.h + cc -c $(CCFLAGS) $(DEFS) direct.c + +rms.o : rms.c rms.h direct.h access.h fibdef.h descrip.h ssdef.h + cc -c $(CCFLAGS) $(DEFS) rms.c + +ods2.o : ods2.c ssdef.h descrip.h access.h rms.h + cc -c $(CCFLAGS) $(DEFS) ods2.c diff --git a/extracters/ods2/memory.h b/extracters/ods2/memory.h new file mode 100644 index 0000000..50d00de --- /dev/null +++ b/extracters/ods2/memory.h @@ -0,0 +1,3 @@ +/* + * Empty placeholder file for VAX C, which doesn't have (or need) + */ diff --git a/extracters/ods2/ods2.c b/extracters/ods2/ods2.c index 759fdad..7e456a1 100644 --- a/extracters/ods2/ods2.c +++ b/extracters/ods2/ods2.c @@ -1,4 +1,7 @@ -/* ODS2.C v1.2 Mainline ODS2 program */ +#define MODULE_NAME ODS2 +#define MODULE_IDENT "V1.3" + +/* Ods2.c v1.3 Mainline ODS2 program */ /* This is part of ODS2 written by Paul Nankervis, @@ -32,6 +35,15 @@ access.c,device.c,cache.c,phyos2.c,vmstime.c */ +/* Modified by: + * + * 31-AUG-2001 01:04 Hunter Goatley + * + * For VMS, added routine getcmd() to read commands with full + * command recall capabilities. + * + */ + /* This version will compile and run using normal VMS I/O by defining VMSIO */ @@ -46,6 +58,16 @@ (sorry! - could be easily fixed though!) */ +#ifdef VMS +#ifdef __DECC +#pragma module MODULE_NAME MODULE_IDENT +#else +#ifdef vaxc +#module MODULE_NAME MODULE_IDENT +#endif /* vaxc */ +#endif /* __DECC */ +#endif /* VMS */ + #define DEBUGx on #define VMSIOx on @@ -53,18 +75,37 @@ #include #include #include -#include "descrip.h" -#include "ssdef.h" + #ifdef VMSIO +#include +#include #include #include -unsigned sys$setddir(); -#else -#include "rms.h" -#include "access.h" -#endif +#include +#define sys_parse sys$parse +#define sys_search sys$search +#define sys_open sys$open +#define sys_close sys$close +#define sys_connect sys$connect +#define sys_disconnect sys$disconnect +#define sys_get sys$get +#define sys_put sys$put +#define sys_create sys$create +#define sys_erase sys$erase +#define sys_extend sys$extend +#define sys_asctim sys$asctim +#define sys_setddir sys$setddir +#define dsc_descriptor dsc$descriptor +#define dsc_w_length dsc$w_length +#define dsc_a_pointer dsc$a_pointer +#else +#include "ssdef.h" +#include "descrip.h" +#include "access.h" +#include "rms.h" +#endif #define PRINT_ATTR (FAB$M_CR | FAB$M_PRN | FAB$M_FTN) @@ -125,7 +166,7 @@ unsigned dir(int argc,char *argv[],int qualc,char *qualv[]) fab.fab$l_dna = "*.*;*"; fab.fab$b_dns = strlen(fab.fab$l_dna); options = checkquals(dirquals,qualc,qualv); - sts = sys$parse(&fab); + sts = sys_parse(&fab); if (sts & 1) { char dir[NAM$C_MAXRSS + 1]; int namelen; @@ -140,7 +181,7 @@ unsigned dir(int argc,char *argv[],int qualc,char *qualv[]) nam.nam$l_rsa = rsa; nam.nam$b_rss = NAM$C_MAXRSS; fab.fab$l_fop = FAB$M_NAM; - while ((sts = sys$search(&fab)) & 1) { + while ((sts = sys_search(&fab)) & 1) { if (dirlen != nam.nam$b_dev + nam.nam$b_dir || memcmp(rsa,dir,nam.nam$b_dev + nam.nam$b_dir) != 0) { if (dirfiles > 0) { @@ -184,11 +225,11 @@ unsigned dir(int argc,char *argv[],int qualc,char *qualv[]) } else { printf("%-19s",rsa + dirlen); } - sts = sys$open(&fab); + sts = sys_open(&fab); if ((sts & 1) == 0) { printf("Open error: %d\n",sts); } else { - sts = sys$close(&fab); + sts = sys_close(&fab); if (options & 2) { char fileid[100]; sprintf(fileid,"(%d,%d,%d)", @@ -204,10 +245,10 @@ unsigned dir(int argc,char *argv[],int qualc,char *qualv[]) } if (options & 1) { char tim[24]; - struct dsc$descriptor timdsc; - timdsc.dsc$w_length = 23; - timdsc.dsc$a_pointer = tim; - sts = sys$asctim(0,&timdsc,&dat.xab$q_cdt,0); + struct dsc_descriptor timdsc; + timdsc.dsc_w_length = 23; + timdsc.dsc_a_pointer = tim; + sts = sys_asctim(0,&timdsc,dat.xab$q_cdt,0); if ((sts & 1) == 0) printf("Asctim error: %d\n",sts); tim[23] = '\0'; printf(" %s",tim); @@ -253,9 +294,11 @@ unsigned dir(int argc,char *argv[],int qualc,char *qualv[]) #define MAXREC 32767 +char *copyquals[] = {"binary",NULL}; + unsigned copy(int argc,char *argv[],int qualc,char *qualv[]) { - int sts; + int sts,options; struct NAM nam = cc$rms_nam; struct FAB fab = cc$rms_fab; char res[NAM$C_MAXRSS + 1],rsa[NAM$C_MAXRSS + 1]; @@ -265,20 +308,21 @@ unsigned copy(int argc,char *argv[],int qualc,char *qualv[]) fab.fab$l_nam = &nam; fab.fab$l_fna = argv[1]; fab.fab$b_fns = strlen(fab.fab$l_fna); - sts = sys$parse(&fab); + options = checkquals(copyquals,qualc,qualv); + sts = sys_parse(&fab); if (sts & 1) { nam.nam$l_rsa = rsa; nam.nam$b_rss = NAM$C_MAXRSS; fab.fab$l_fop = FAB$M_NAM; - while ((sts = sys$search(&fab)) & 1) { - sts = sys$open(&fab); + while ((sts = sys_search(&fab)) & 1) { + sts = sys_open(&fab); if ((sts & 1) == 0) { printf("%%COPY-F-OPENFAIL, Open error: %d\n",sts); perror("-COPY-F-ERR "); } else { struct RAB rab = cc$rms_rab; rab.rab$l_fab = &fab; - if ((sts = sys$connect(&rab)) & 1) { + if ((sts = sys_connect(&rab)) & 1) { FILE *tof; char name[NAM$C_MAXRSS + 1]; unsigned records = 0; @@ -308,7 +352,15 @@ unsigned copy(int argc,char *argv[],int qualc,char *qualv[]) } *out++ = '\0'; } +#ifndef _WIN32 tof = fopen(name,"w"); +#else + if ((options & 1) == 0 && fab.fab$b_rat & PRINT_ATTR) { + tof = fopen(name,"w"); + } else { + tof = fopen(name,"wb"); + } +#endif if (tof == NULL) { printf("%%COPY-F-OPENOUT, Could not open %s\n",name); perror("-COPY-F-ERR "); @@ -317,9 +369,10 @@ unsigned copy(int argc,char *argv[],int qualc,char *qualv[]) filecount++; rab.rab$l_ubf = rec; rab.rab$w_usz = MAXREC; - while ((sts = sys$get(&rab)) & 1) { + while ((sts = sys_get(&rab)) & 1) { unsigned rsz = rab.rab$w_rsz; - if (fab.fab$b_rat & PRINT_ATTR) rec[rsz++] = '\n'; + if ((options & 1) == 0 && + fab.fab$b_rat & PRINT_ATTR) rec[rsz++] = '\n'; if (fwrite(rec,rsz,1,tof) == 1) { records++; } else { @@ -333,15 +386,17 @@ unsigned copy(int argc,char *argv[],int qualc,char *qualv[]) perror("-COPY-F-ERR "); } } - sys$disconnect(&rab); + sys_disconnect(&rab); + rsa[nam.nam$b_rsl] = '\0'; if (sts == RMS$_EOF) { - rsa[nam.nam$b_rsl] = '\0'; printf("%%COPY-S-COPIED, %s copied to %s (%d record%s)\n", rsa,name,records,(records == 1 ? "" : "s")); + } else { + printf("%%COPY-F-ERROR Status: %d for %s\n",sts,rsa); sts = 1; } } - sys$close(&fab); + sys_close(&fab); } } if (sts == RMS$_NMF) sts = 1; @@ -355,6 +410,44 @@ unsigned copy(int argc,char *argv[],int qualc,char *qualv[]) return sts; } +/* import: a file copy routine */ + + +unsigned import(int argc,char *argv[],int qualc,char *qualv[]) +{ + int sts; + FILE *fromf; + fromf = fopen(argv[1],"r"); + if (fromf != NULL) { + struct FAB fab = cc$rms_fab; + fab.fab$l_fna = argv[2]; + fab.fab$b_fns = strlen(fab.fab$l_fna); + if ((sts = sys_create(&fab)) & 1) { + struct RAB rab = cc$rms_rab; + rab.rab$l_fab = &fab; + if ((sts = sys_connect(&rab)) & 1) { + char rec[MAXREC + 2]; + rab.rab$l_rbf = rec; + rab.rab$w_usz = MAXREC; + while (fgets(rec,sizeof(rec),fromf) != NULL) { + rab.rab$w_rsz = strlen(rec); + sts = sys_put(&rab); + if ((sts & 1) == 0) break; + } + sys_disconnect(&rab); + } + sys_close(&fab); + } + fclose(fromf); + if (!(sts & 1)) { + printf("%%IMPORT-F-ERROR Status: %d\n",sts); + } + } else { + printf("Can't open %s\n",argv[1]); + } + return sts; +} + /* diff: a simple file difference routine */ @@ -371,14 +464,14 @@ unsigned diff(int argc,char *argv[],int qualc,char *qualv[]) printf("Could not open file %s\n",argv[1]); sts = 0; } else { - if ((sts = sys$open(&fab)) & 1) { + if ((sts = sys_open(&fab)) & 1) { struct RAB rab = cc$rms_rab; rab.rab$l_fab = &fab; - if ((sts = sys$connect(&rab)) & 1) { + if ((sts = sys_connect(&rab)) & 1) { char rec[MAXREC + 2],cpy[MAXREC + 1]; rab.rab$l_ubf = rec; rab.rab$w_usz = MAXREC; - while ((sts = sys$get(&rab)) & 1) { + while ((sts = sys_get(&rab)) & 1) { strcpy(rec + rab.rab$w_rsz,"\n"); fgets(cpy,MAXREC,tof); if (strcmp(rec,cpy) != 0) { @@ -389,9 +482,9 @@ unsigned diff(int argc,char *argv[],int qualc,char *qualv[]) records++; } } - sys$disconnect(&rab); + sys_disconnect(&rab); } - sys$close(&fab); + sys_close(&fab); } fclose(tof); if (sts == RMS$_EOF) sts = 1; @@ -414,23 +507,23 @@ unsigned typ(int argc,char *argv[],int qualc,char *qualv[]) struct FAB fab = cc$rms_fab; fab.fab$l_fna = argv[1]; fab.fab$b_fns = strlen(fab.fab$l_fna); - if ((sts = sys$open(&fab)) & 1) { + if ((sts = sys_open(&fab)) & 1) { struct RAB rab = cc$rms_rab; rab.rab$l_fab = &fab; - if ((sts = sys$connect(&rab)) & 1) { + if ((sts = sys_connect(&rab)) & 1) { char rec[MAXREC + 2]; rab.rab$l_ubf = rec; rab.rab$w_usz = MAXREC; - while ((sts = sys$get(&rab)) & 1) { + while ((sts = sys_get(&rab)) & 1) { unsigned rsz = rab.rab$w_rsz; if (fab.fab$b_rat & PRINT_ATTR) rec[rsz++] = '\n'; rec[rsz++] = '\0'; fputs(rec,stdout); records++; } - sys$disconnect(&rab); + sys_disconnect(&rab); } - sys$close(&fab); + sys_close(&fab); if (sts == RMS$_EOF) sts = 1; } if ((sts & 1) == 0) { @@ -470,25 +563,25 @@ unsigned search(int argc,char *argv[],int qualc,char *qualv[]) fab.fab$b_fns = strlen(fab.fab$l_fna); fab.fab$l_dna = ""; fab.fab$b_dns = strlen(fab.fab$l_dna); - sts = sys$parse(&fab); + sts = sys_parse(&fab); if (sts & 1) { nam.nam$l_rsa = rsa; nam.nam$b_rss = NAM$C_MAXRSS; fab.fab$l_fop = FAB$M_NAM; - while ((sts = sys$search(&fab)) & 1) { - sts = sys$open(&fab); + while ((sts = sys_search(&fab)) & 1) { + sts = sys_open(&fab); if ((sts & 1) == 0) { printf("%%SEARCH-F-OPENFAIL, Open error: %d\n",sts); } else { struct RAB rab = cc$rms_rab; rab.rab$l_fab = &fab; - if ((sts = sys$connect(&rab)) & 1) { + if ((sts = sys_connect(&rab)) & 1) { int printname = 1; char rec[MAXREC + 2]; filecount++; rab.rab$l_ubf = rec; rab.rab$w_usz = MAXREC; - while ((sts = sys$get(&rab)) & 1) { + while ((sts = sys_get(&rab)) & 1) { register char *strng = rec; register char *strngend = strng + (rab.rab$w_rsz - (searend - searstr)); while (strng < strngend) { @@ -517,13 +610,13 @@ unsigned search(int argc,char *argv[],int qualc,char *qualv[]) } } } - sys$disconnect(&rab); + sys_disconnect(&rab); } if (sts == SS$_NOTINSTALL) { printf("%%SEARCH-W-NOIMPLEM, file operation not implemented\n"); sts = 1; } - sys$close(&fab); + sys_close(&fab); } } if (sts == RMS$_NMF || sts == RMS$_FNF) sts = 1; @@ -555,8 +648,7 @@ unsigned del(int argc,char *argv[],int qualc,char *qualv[]) fab.fab$l_nam = &nam; fab.fab$l_fna = argv[1]; fab.fab$b_fns = strlen(fab.fab$l_fna); - printf("WARNING! This bit is broken - volume corruption VERY likely!\n"); - sts = sys$parse(&fab); + sts = sys_parse(&fab); if (sts & 1) { if (nam.nam$b_ver < 2) { printf("%%DELETE-F-NOVER, you must specify a version!!\n"); @@ -564,8 +656,8 @@ unsigned del(int argc,char *argv[],int qualc,char *qualv[]) nam.nam$l_rsa = rsa; nam.nam$b_rss = NAM$C_MAXRSS; fab.fab$l_fop = FAB$M_NAM; - while ((sts = sys$search(&fab)) & 1) { - sts = sys$erase(&fab); + while ((sts = sys_search(&fab)) & 1) { + sts = sys_erase(&fab); if ((sts & 1) == 0) { printf("%%DELETE-F-DELERR, Delete error: %d\n",sts); } else { @@ -587,6 +679,40 @@ unsigned del(int argc,char *argv[],int qualc,char *qualv[]) return sts; } +/* test: you don't want to know! */ +struct VCB *test_vcb; + +unsigned test(int argc,char *argv[],int qualc,char *qualv[]) +{ + int sts = 0; + struct fiddef fid; + sts = update_create(test_vcb,NULL,"Test.File",&fid,NULL); + printf("Test status of %d (%s)\n",sts,argv[1]); + return sts; +} + +/* more test code... */ + +unsigned extend(int argc,char *argv[],int qualc,char *qualv[]) +{ + int sts; + struct FAB fab = cc$rms_fab; + fab.fab$l_fna = argv[1]; + fab.fab$b_fns = strlen(fab.fab$l_fna); + fab.fab$b_fac = FAB$M_UPD; + if ((sts = sys_open(&fab)) & 1) { + fab.fab$l_alq = 32; + sts = sys_extend(&fab); + sys_close(&fab); + } + if ((sts & 1) == 0) { + printf("%%EXTEND-F-ERROR Status: %d\n",sts); + } + return sts; +} + + + /* show: the show command */ @@ -596,10 +722,10 @@ unsigned show(int argc,char *argv[],int qualc,char *qualv[]) if (keycomp(argv[1],"default")) { unsigned short curlen; char curdir[NAM$C_MAXRSS + 1]; - struct dsc$descriptor curdsc; - curdsc.dsc$w_length = NAM$C_MAXRSS; - curdsc.dsc$a_pointer = curdir; - if ((sts = sys$setddir(NULL,&curlen,&curdsc)) & 1) { + struct dsc_descriptor curdsc; + curdsc.dsc_w_length = NAM$C_MAXRSS; + curdsc.dsc_a_pointer = curdir; + if ((sts = sys_setddir(NULL,&curlen,&curdsc)) & 1) { curdir[curlen] = '\0'; printf(" %s\n",curdir); } else { @@ -607,14 +733,19 @@ unsigned show(int argc,char *argv[],int qualc,char *qualv[]) } } else { if (keycomp(argv[1],"time")) { + unsigned sts; char timstr[24]; unsigned short timlen; - struct dsc$descriptor timdsc; - timdsc.dsc$w_length = 23; - timdsc.dsc$a_pointer = timstr; - sys$asctim(&timlen,&timdsc,NULL,0); - timstr[timlen] = '\0'; - printf(" %s\n",timstr); + struct dsc_descriptor timdsc; + timdsc.dsc_w_length = 20; + timdsc.dsc_a_pointer = timstr; + sts = sys_asctim(&timlen,&timdsc,NULL,0); + if (sts & 1) { + timstr[timlen] = '\0'; + printf(" %s\n",timstr); + } else { + printf("%%SHOW-W-TIMERR error %d\n",sts); + } } else { printf("%%SHOW-W-WHAT '%s'?\n",argv[1]); } @@ -622,18 +753,28 @@ unsigned show(int argc,char *argv[],int qualc,char *qualv[]) return sts; } +unsigned setdef_count = 0; + +void setdef(char *newdef) +{ + register unsigned sts; + struct dsc_descriptor defdsc; + defdsc.dsc_a_pointer = newdef; + defdsc.dsc_w_length = strlen(defdsc.dsc_a_pointer); + if ((sts = sys_setddir(&defdsc,NULL,NULL)) & 1) { + setdef_count++; + } else { + printf("Error %d setting default to %s\n",sts,newdef); + } +} + /* set: the set command */ unsigned set(int argc,char *argv[],int qualc,char *qualv[]) { unsigned sts = 1; if (keycomp(argv[1],"default")) { - struct dsc$descriptor defdsc; - defdsc.dsc$a_pointer = argv[2]; - defdsc.dsc$w_length = strlen(defdsc.dsc$a_pointer); - if (((sts = sys$setddir(&defdsc,NULL,NULL)) & 1) == 0) { - printf("Error %d setting default to %s\n",sts,argv[2]); - } + setdef(argv[2]); } else { printf("%%SET-W-WHAT '%s'?\n",argv[1]); } @@ -660,6 +801,8 @@ unsigned dodismount(int argc,char *argv[],int qualc,char *qualv[]) return sts; } + + char *mouquals[] = {"write",NULL}; unsigned domount(int argc,char *argv[],int qualc,char *qualv[]) @@ -697,6 +840,15 @@ unsigned domount(int argc,char *argv[],int qualc,char *qualv[]) if (vcb->vcbdev[i].dev != NULL) printf("%%MOUNT-I-MOUNTED, Volume %12.12s mounted on %s\n", vcb->vcbdev[i].home.hm2$t_volname,vcb->vcbdev[i].dev->devnam); + if (setdef_count == 0) { + char *colon,defdir[256]; + strcpy(defdir,vcb->vcbdev[0].dev->devnam); + colon = strchr(defdir,':'); + if (colon != NULL) *colon = '\0'; + strcpy(defdir + strlen(defdir),":[000000]"); + setdef(defdir); + test_vcb = vcb; + } } else { printf("Mount failed with %d\n",sts); } @@ -705,7 +857,7 @@ unsigned domount(int argc,char *argv[],int qualc,char *qualv[]) } -void directshow(void); +void direct_show(void); void phyio_show(void); /* statis: print some simple statistics */ @@ -713,20 +865,12 @@ void phyio_show(void); unsigned statis(int argc,char *argv[],int qualc,char *qualv[]) { printf("Statistics:-\n"); - directshow(); - cacheshow(); + direct_show(); + cache_show(); phyio_show(); return 1; } -/* dump: a simple debugging aid */ - -unsigned dump(int argc,char *argv[],int qualc,char *qualv[]) -{ - printf("Cache Dump:-\n"); - cachedump(); - return 1; -} #endif @@ -734,14 +878,14 @@ unsigned dump(int argc,char *argv[],int qualc,char *qualv[]) unsigned help(int argc,char *argv[],int qualc,char *qualv[]) { - printf("\nODS2 v1.2\n"); + printf("\nODS2 %s\n", MODULE_IDENT); printf(" Please send problems/comments to Paulnank@au1.ibm.com\n"); printf(" Commands are:\n"); printf(" copy difference directory exit\n"); printf(" mount show_default show_time search\n"); printf(" set_default type\n"); printf(" Example:-\n $ mount e:\n"); - printf(" $ search e:[vms$common.decc*...]*.h rms$_wld\n"); + printf(" $ search e:[vms_common.decc*...]*.h rms$_wld\n"); printf(" $ set default e:[sys0.sysmgr]\n"); printf(" $ copy *.com;-1 c:\\*.*\n"); printf(" $ directory/file/size/date [-.sys*...].%%\n"); @@ -755,13 +899,16 @@ unsigned help(int argc,char *argv[],int qualc,char *qualv[]) struct CMDSET { char *name; unsigned (*proc) (int argc,char *argv[],int qualc,char *qualv[]); - unsigned int minlen; - unsigned int minargs; - unsigned int maxargs; - unsigned int maxquals; + int minlen; + int minargs; + int maxargs; + int maxquals; } cmdset[] = { { - "copy",copy,3,3,3,0 + "copy",copy,3,3,3,1 +}, + { + "import",import,3,3,3,0 }, { "delete",del,3,2,2,0 @@ -774,9 +921,15 @@ struct CMDSET { }, { "exit",NULL,2,0,0,0 +}, + { + "extend",extend,3,2,2,0 }, { "help",help,2,1,1,0 +}, + { + "quit",NULL,2,0,0,0 }, { "show",show,2,2,2,0 @@ -796,11 +949,11 @@ struct CMDSET { }, { "statistics",statis,3,1,1,0 -}, - { - "dump",dump,3,1,1,0 }, #endif + { + "test",test,4,2,2,0 +}, { "type",typ,3,2,2,0 }, @@ -812,7 +965,7 @@ struct CMDSET { /* cmdexecute: identify and execute a command */ -int cmdexecute(unsigned int argc,char *argv[],unsigned int qualc,char *qualv[]) +int cmdexecute(int argc,char *argv[],int qualc,char *qualv[]) { char *ptr = argv[0]; struct CMDSET *cmd = cmdset; @@ -835,7 +988,7 @@ int cmdexecute(unsigned int argc,char *argv[],unsigned int qualc,char *qualv[]) } else { (*cmd->proc) (argc,argv,qualc,qualv); #ifndef VMSIO - cacheflush(); + /* cache_flush(); */ #endif } } @@ -879,18 +1032,89 @@ int cmdsplit(char *str) return 1; } +#ifdef VMS +#include +#include + +char *getcmd(char *inp, char *prompt) +{ + struct dsc_descriptor prompt_d = {strlen(prompt),DSC$K_DTYPE_T, + DSC$K_CLASS_S, prompt}; + struct dsc_descriptor input_d = {1024,DSC$K_DTYPE_T, + DSC$K_CLASS_S, inp}; + int status; + char *retstat; + static unsigned long key_table_id = 0; + static unsigned long keyboard_id = 0; + + if (key_table_id == 0) + { + status = smg$create_key_table (&key_table_id); + if (status & 1) + status = smg$create_virtual_keyboard (&keyboard_id); + if (!(status & 1)) return (NULL); + } + + status = smg$read_composed_line (&keyboard_id, &key_table_id, + &input_d, &prompt_d, &input_d, 0,0,0,0,0,0,0); + + if (status == SMG$_EOF) + retstat = NULL; + else + { + inp[input_d.dsc_w_length] = '\0'; + retstat = inp; + } + + return(retstat); +} +#endif /* VMS */ + /* main: the simple mainline of this puppy... */ int main(int argc,char *argv[]) { char str[2048]; - str[sizeof(str)-1] = 0; - printf(" ODS2 v1.2\n"); + FILE *atfile = NULL; + printf(" ODS2 %s\n", MODULE_IDENT); while (1) { - printf("$> "); - if (fgets(str, sizeof(str)-1, stdin) == NULL) break; - if (strlen(str)) if ((cmdsplit(str) & 1) == 0) break; + char *ptr; + if (atfile != NULL) { + if (fgets(str,sizeof(str),atfile) == NULL) { + fclose(atfile); + atfile = NULL; + *str = '\0'; + } else { + ptr = strchr(str,'\n'); + if (ptr != NULL) *ptr = '\0'; + printf("$> %s\n",str); + } + } else { +#ifdef VMS + if (getcmd (str, "$> ") == NULL) break; +#else + printf("$> "); + if (gets(str) == NULL) break; +#endif + } + ptr = str; + while (*ptr == ' ' || *ptr == '\t') ptr++; + if (strlen(ptr) && *ptr != '!') { + if (*ptr == '@') { + if (atfile != NULL) { + printf("%%ODS2-W-INDIRECT, indirect indirection not permitted\n"); + } else { + if ((atfile = fopen(ptr + 1,"r")) == NULL) { + perror("%%Indirection failed"); + printf("\n"); + } + } + } else { + if ((cmdsplit(ptr) & 1) == 0) break; + } + } } + if (atfile != NULL) fclose(atfile); return 1; } diff --git a/extracters/ods2/ods2.rc b/extracters/ods2/ods2.rc new file mode 100644 index 0000000..879ac3c --- /dev/null +++ b/extracters/ods2/ods2.rc @@ -0,0 +1,109 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,3 + PRODUCTVERSION 1,0,0,3 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "This application reads ODS-2 (VMS) disks under Windows NT and Windows 2000\0" + VALUE "CompanyName", "Paul Nankervis \0" + VALUE "FileDescription", "ODS-2 Reader for Windows\0" + VALUE "FileVersion", "V1.3\0" + VALUE "InternalName", "ODS2\0" + VALUE "LegalCopyright", "Copyright © 2001\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "ODS2.EXE\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "ODS2\0" + VALUE "ProductVersion", "V1.3\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/extracters/ods2/ods2_alpha.exe b/extracters/ods2/ods2_alpha.exe new file mode 100644 index 0000000000000000000000000000000000000000..c3622ea4c643ed8c07e85290be67e1217d03c405 GIT binary patch literal 79872 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 z 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νj@2m#GPd*U|IU+}pY!LpmlrUaH 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�*4oLfq4RZg9dFkuu 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 literal 0 HcmV?d00001 diff --git a/extracters/ods2/ods2_tru64.exe b/extracters/ods2/ods2_tru64.exe new file mode 100644 index 0000000000000000000000000000000000000000..d94945f9956125311faf667ebe87adaf1d115757 GIT binary patch literal 217088 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�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 literal 0 HcmV?d00001 diff --git a/extracters/ods2/ods2_vax_vaxc.exe b/extracters/ods2/ods2_vax_vaxc.exe new file mode 100644 index 0000000000000000000000000000000000000000..57c45616c5782f33a64b3c9f23250ab579889f7b GIT binary patch literal 40448 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 bJ8!dAnOCentXKRTfS<2&eE#?U$$|d?n4ciD literal 0 HcmV?d00001 diff --git a/extracters/ods2/ods2_win32.exe b/extracters/ods2/ods2_win32.exe new file mode 100644 index 0000000000000000000000000000000000000000..1131c20164e8be7b7244b6f58cc6a50a4405d9e4 GIT binary patch literal 69632 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 f&yUPk>q{qJ?>hs2b|9Yef+(MQd #include @@ -26,48 +24,13 @@ #include #include -#include "phyio.h" #include "ssdef.h" -unsigned init_count = 0; /* Some counters so we can report */ -unsigned read_count = 0; /* How often we get called */ -unsigned write_count = 0; - -void phyio_show(void) -{ - printf("PHYIO_SHOW Initializations: %d Reads: %d Writes: %d\n", - init_count,read_count,write_count); -} - - -unsigned phyio_write(unsigned handle,unsigned block,unsigned length,char *buffer) -{ - write_count++; - return SS$_WRITLCK; /* Not implemented yet!! */ -} - - -/* This routine figures out whether this is an NT system or not... */ - -unsigned is_NT = 2; -OSVERSIONINFO sysver; - -void getsysversion() -{ - memset(&sysver,0,sizeof(OSVERSIONINFO)); - sysver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&sysver); - if (sysver.dwPlatformId == VER_PLATFORM_WIN32_NT) { - is_NT = 1; - } else { - is_NT = 0; - } -} /* - To read from CD APSI run-time support is required (wnaspi32.dll). - NT does not come with APSI support so you need to install it first. + To read from CD ASPI run-time support is required (wnaspi32.dll). + NT does not come with ASPI support so you need to install it first. (ASPI is also required for things like Digital Audio Extraction and was origionally loaded on my machine to make MP3 audio files.) One downside is that ASPI on NT does not have a way to match SCSI @@ -79,108 +42,205 @@ void getsysversion() you find a better way please let me know... Paulnank@au1.ibm.com */ -#if defined (USE_WNASPI) - #include "wnaspi32.h" +#include "scsidefs.h" -unsigned cd_initialized = 0; /* Flag for CD read to go... */ -unsigned cd_adaptor,cd_target; /* Adaptor & SCSI #'s */ -HANDLE ASPICompletion; /* Windows event for ASPI wait */ +unsigned ASPI_status = 0; /* Temporary status indicator */ +unsigned ASPI_HaStat = 0; /* Temporary status indicator */ +unsigned ASPI_TargStat = 0; /* Temporary status indicator */ +HANDLE ASPI_event; /* Windows event for ASPI wait */ +SRB_ExecSCSICmd ASPI_srb; /* SRB buffer for ASPI commands */ -/* Get ASPI ready and locate the first CD drive... */ - -unsigned cd_initialize() +unsigned aspi_execute(short bus,short id,BYTE Flags,DWORD BufLen, + BYTE *BufPointer,BYTE CDBLen,BYTE CDBByte) { - if (cd_initialized) { - printf("Can only support one (first) ASPI device\n"); - return 8; - } else { - DWORD ASPIStatus; + ASPI_srb.SRB_Cmd = SC_EXEC_SCSI_CMD; + ASPI_srb.SRB_Status = SS_PENDING; + ASPI_srb.SRB_HaId = bus; + ASPI_srb.SRB_Flags = Flags | SRB_EVENT_NOTIFY; + ASPI_srb.SRB_Hdr_Rsvd = 0; + ASPI_srb.SRB_Target = id; + ASPI_srb.SRB_Lun = 0; + ASPI_srb.SRB_Rsvd1 = 0; + ASPI_srb.SRB_BufLen = BufLen; + ASPI_srb.SRB_BufPointer = BufPointer; + ASPI_srb.SRB_SenseLen = SENSE_LEN; + ASPI_srb.SRB_CDBLen = CDBLen; + ASPI_srb.SRB_HaStat = 0; + ASPI_srb.SRB_TargStat = 0; + ASPI_srb.SRB_PostProc = ASPI_event; + ASPI_srb.SRB_Rsvd2 = NULL; + memset(ASPI_srb.SRB_Rsvd3,0,sizeof(ASPI_srb.SRB_Rsvd3)); + ASPI_srb.CDBByte[0] = CDBByte; + SendASPI32Command(&ASPI_srb); /* Perform the command... */ + while (ASPI_srb.SRB_Status == SS_PENDING) + WaitForSingleObject(ASPI_event,INFINITE); + ResetEvent(ASPI_event); + ASPI_status = ASPI_srb.SRB_Status; + ASPI_HaStat = ASPI_srb.SRB_HaStat; + ASPI_TargStat = ASPI_srb.SRB_TargStat; + if (ASPI_srb.SRB_Status != SS_COMP) return SS$_PARITY; + return 1; +} + + +/* Read a sector using ASPI... */ + +unsigned aspi_read(short bus,short id,unsigned sector,unsigned sectorsize,char *buffer) +{ + + ASPI_srb.CDBByte[1] = 0; + ASPI_srb.CDBByte[2] = (sector >> 24); + ASPI_srb.CDBByte[3] = (sector >> 16) & 0xff; + ASPI_srb.CDBByte[4] = (sector >> 8) & 0xff; + ASPI_srb.CDBByte[5] = sector & 0xff; + ASPI_srb.CDBByte[6] = 0; + ASPI_srb.CDBByte[7] = 0; + ASPI_srb.CDBByte[8] = 1; /* Read a single sector */ + ASPI_srb.CDBByte[9] = 0; + return aspi_execute(bus,id,SRB_DIR_IN,sectorsize,buffer,10,SCSI_READ10); +} + + +/* Write a sector using ASPI... */ + +unsigned aspi_write(short bus,short id,unsigned sector,unsigned sectorsize,char *buffer) +{ + + ASPI_srb.CDBByte[1] = 0; + ASPI_srb.CDBByte[2] = (sector >> 24); + ASPI_srb.CDBByte[3] = (sector >> 16) & 0xff; + ASPI_srb.CDBByte[4] = (sector >> 8) & 0xff; + ASPI_srb.CDBByte[5] = sector & 0xff; + ASPI_srb.CDBByte[6] = 0; + ASPI_srb.CDBByte[7] = 0; + ASPI_srb.CDBByte[8] = 1; /* Read a single sector */ + ASPI_srb.CDBByte[9] = 0; + return aspi_execute(bus,id,SRB_DIR_OUT,sectorsize,buffer,10,SCSI_WRITE10); +} + + +/* Routine to identify a device found by ASPI */ + +unsigned aspi_identify(short bus,short id,unsigned *sectsize) +{ + struct SCSI_Inquiry { + unsigned char device; + unsigned char dev_qual2; + unsigned char version; + unsigned char response_format; + unsigned char additional_length; + unsigned char unused[2]; + unsigned char flags; + char vendor[8]; + char product[16]; + char revision[4]; + unsigned char extra[60]; + } InquiryBuffer; + unsigned sts; + ASPI_srb.CDBByte[1] = 0; /* SCSI Inquiry packet */ + ASPI_srb.CDBByte[2] = 0; + ASPI_srb.CDBByte[3] = 0; + ASPI_srb.CDBByte[4] = sizeof(InquiryBuffer); + ASPI_srb.CDBByte[5] = 0; + sts = aspi_execute(bus,id,SRB_DIR_IN,sizeof(InquiryBuffer),(BYTE *)&InquiryBuffer,6,SCSI_INQUIRY); + if (sts & 1) { + ASPI_srb.CDBByte[1] = 0;/* SCSI TEST if ready packet */ + ASPI_srb.CDBByte[2] = 0; + ASPI_srb.CDBByte[3] = 0; + ASPI_srb.CDBByte[4] = 0; + ASPI_srb.CDBByte[5] = 0; + sts = aspi_execute(bus,id,0,0,NULL,6,SCSI_TST_U_RDY); + if ((sts & 1) == 0) { + ASPI_srb.CDBByte[1] = 0; /* SCSI START STOP packet */ + ASPI_srb.CDBByte[2] = 0; + ASPI_srb.CDBByte[3] = 0; + ASPI_srb.CDBByte[4] = 1; /* Start unit */ + ASPI_srb.CDBByte[5] = 0; + sts = aspi_execute(bus,id,0,0,NULL,6,SCSI_START_STP); + } + if (sts & 1) { + struct { + unsigned char blocks[4]; + unsigned char sectsz[4]; + } CapBuffer; + memset(ASPI_srb.CDBByte,0,sizeof(ASPI_srb.CDBByte)); + sts = aspi_execute(bus,id,SRB_DIR_IN,sizeof(CapBuffer),(BYTE *)&CapBuffer,10,SCSI_RD_CAPAC); + if (sts & 1) { + *sectsize = (CapBuffer.sectsz[0] << 24) | (CapBuffer.sectsz[1] << 16) | + (CapBuffer.sectsz[2] << 8) | CapBuffer.sectsz[3]; + } + } + printf("ASPI (Bus %d,ID %d) %8.8s %16.16s %4.4s %s %d\n",bus,id, + InquiryBuffer.vendor,InquiryBuffer.product,InquiryBuffer.revision, + (InquiryBuffer.dev_qual2 & 0x80) ? "Removable" : "Fixed",*sectsize); + + } + if ((sts & 1) == 0) { + int i; + printf("ASPI Error sense %x %x %x - ",ASPI_status,ASPI_HaStat,ASPI_TargStat); + for (i = 0; i < SENSE_LEN; i++) printf(" %x",ASPI_srb.SenseArea[i]); + printf("\n"); + } + return sts; +} + + + +unsigned ASPI_adapters = 0; /* Count of ASPI adapters */ +unsigned ASPI_devices = 0; /* Count of ASPI devices we have accessed */ + +/* Get ASPI ready and locate the next ASPI drive... */ + +unsigned aspi_initialize(short *dev_type,short *dev_bus,short *dev_id,unsigned *sectsize) +{ + short aspi_bus,aspi_id; + unsigned aspi_devcount = 0; + DWORD ASPIStatus; + SRB_GDEVBlock Ssrb; + if (ASPI_adapters == 0) { ASPIStatus = GetASPI32SupportInfo(); - if (HIBYTE(LOWORD(ASPIStatus)) == SS_COMP) { - BYTE NumAdapters; - SRB_GDEVBlock Ssrb; - Ssrb.SRB_Cmd = SC_GET_DEV_TYPE; - Ssrb.SRB_HaId = 0; - Ssrb.SRB_Flags = SRB_EVENT_NOTIFY; - Ssrb.SRB_Hdr_Rsvd = 0; - Ssrb.SRB_Target = 0; - Ssrb.SRB_Lun = 0; - NumAdapters = LOWORD(LOBYTE(ASPIStatus)); - for (cd_adaptor = 0; cd_adaptor < NumAdapters; cd_adaptor++) { - for (cd_target = 0; cd_target <= 7; cd_target++) { - Ssrb.SRB_HaId = cd_adaptor; - Ssrb.SRB_Target = cd_target; - ASPIStatus = SendASPI32Command(&Ssrb); - if (ASPIStatus == SS_COMP && Ssrb.SRB_DeviceType == 5) break; - } - if (cd_target <= 7) break; - } - if (cd_adaptor < NumAdapters) { - if ((ASPICompletion = CreateEvent(NULL,FALSE,FALSE,NULL)) == NULL) return 8; - cd_initialized = 1; - return 1; - } else { - printf("Could not find ASPI CD device\n"); - return 8; - } - } else { + ASPI_status = ASPIStatus; + if (HIBYTE(LOWORD(ASPIStatus)) != SS_COMP) { printf("Could not initialize ASPI (%x)\n",ASPIStatus); + printf("Please check that ASPI is installed and started properly\n"); return 8; + } else { + ASPI_adapters = LOWORD(LOBYTE(ASPIStatus)); + if ((ASPI_event = CreateEvent(NULL,FALSE,FALSE,NULL)) == NULL) return 8; } } + Ssrb.SRB_Cmd = SC_GET_DEV_TYPE; + Ssrb.SRB_HaId = 0; + Ssrb.SRB_Flags = SRB_EVENT_NOTIFY; + Ssrb.SRB_Hdr_Rsvd = 0; + Ssrb.SRB_Lun = 0; + for (aspi_bus = 0; aspi_bus < ASPI_adapters; aspi_bus++) { + for (aspi_id = 0; aspi_id <= 7; aspi_id++) { + Ssrb.SRB_HaId = aspi_bus; + Ssrb.SRB_Target = aspi_id; + ASPIStatus = SendASPI32Command(&Ssrb); + ASPI_status = ASPIStatus; + if (ASPIStatus == SS_COMP) { + if (Ssrb.SRB_DeviceType == DTYPE_CROM || Ssrb.SRB_DeviceType == DTYPE_OPTI) { + if (++aspi_devcount > ASPI_devices) { + unsigned sts = aspi_identify(aspi_bus,aspi_id,sectsize); + *dev_type = Ssrb.SRB_DeviceType; + *dev_bus = aspi_bus; + *dev_id = aspi_id; + ASPI_devices++; + return 1; + } + } + } + } + } + printf("Could not find suitable ASPI device\n"); + return 8; } -/* Read a sector from CD using ASPI... */ - -unsigned cd_read(unsigned sector,char *buffer) -{ - DWORD ASPIEventStatus; - SRB_ExecSCSICmd Esrb; - Esrb.SRB_Cmd = SC_EXEC_SCSI_CMD; - Esrb.SRB_HaId = cd_adaptor; - Esrb.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - Esrb.SRB_Hdr_Rsvd = 0; - Esrb.SRB_Target = cd_target; - Esrb.SRB_Lun = 0; - Esrb.SRB_BufLen = 2352; - Esrb.SRB_BufPointer = buffer; - Esrb.SRB_SenseLen = 0; - Esrb.SRB_CDBLen = 10; - Esrb.SRB_PostProc = ASPICompletion; - Esrb.CDBByte[0] = 0x28; /* Build SCSI read command packet... */ - Esrb.CDBByte[1] = 0; - Esrb.CDBByte[2] = (sector >> 24); - Esrb.CDBByte[3] = (sector >> 16) & 0xff; - Esrb.CDBByte[4] = (sector >> 8) & 0xff; - Esrb.CDBByte[5] = sector & 0xff; - Esrb.CDBByte[6] = 0; - Esrb.CDBByte[7] = 0; - Esrb.CDBByte[8] = 1; - Esrb.CDBByte[9] = 0; - Esrb.CDBByte[10] = 0; - SendASPI32Command(&Esrb); /* Perform the read... */ - while (Esrb.SRB_Status == SS_PENDING) - ASPIEventStatus = WaitForSingleObject(ASPICompletion,INFINITE); - /* if (ASPIEventStatus == WAIT_OBJECT_0) */ResetEvent(ASPICompletion); - if (Esrb.SRB_Status != SS_COMP) return SS$_PARITY; - return 1; -} -#else /* !defined(USE_WNASPI) */ - -unsigned cd_initialize() -{ - return 1; -} - -unsigned cd_read(unsigned sector,char *buffer) -{ - return 0; -} - -#endif /* defined(USE_WNASPI) */ /* Some NT definitions... */ @@ -218,7 +278,7 @@ BOOL sizeof(*dGeometry), &ReturnedByteCount, NULL - ); + ); return results; } @@ -279,6 +339,22 @@ typedef struct _DEVICEPARAM { +/* This routine figures out whether this is an NT system or not... */ + +unsigned is_NT = 2; +OSVERSIONINFO sysver; + +void getsysversion(void) +{ + memset(&sysver,0,sizeof(OSVERSIONINFO)); + sysver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&sysver); + if (sysver.dwPlatformId == VER_PLATFORM_WIN32_NT) { + is_NT = 1; + } else { + is_NT = 0; + } +} /* Each device we talk to has a channel entry so that we can remember its details... */ @@ -290,154 +366,24 @@ struct CHANTAB { char *IoBuffer; /* Pointer to a buffer for the device */ unsigned sectorsize; /* Device sector size */ unsigned last_sector; /* Last sector no read (still in buffer) */ - short device_type; /* Flag for 'normal' or ASPI I/O */ + short device_status; /* Device status bits */ short device_name; /* Drive letter (A, B, C, ...) */ + short device_dtype; /* Type of disk... */ + short device_bus; /* ASPI device bus */ + short device_id; /* ASPI device id */ } chantab[CHAN_MAX]; - -/* Initialize device by opening it, locking it and getting it ready.. */ - -unsigned phyio_init(int devlen,char *devnam,unsigned *chanptr,struct phyio_info *info) -{ - unsigned sts = 1; - unsigned chan = chan_count; - if (is_NT > 1) getsysversion(); - if (chan < CHAN_MAX - 1 && devlen == 2 && - toupper(*devnam) >= 'A' && *(devnam + 1) == ':') { - HANDLE hDrive; - chantab[chan].device_name = toupper(*devnam); - chantab[chan].device_type = 0; - - /* NT stuff */ - - if (is_NT) { - char ntname[32]; - DISK_GEOMETRY Geometry; - sprintf(ntname,"\\\\.\\%s",devnam); - chantab[chan].handle = hDrive = CreateFileA( - ntname, - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_NO_BUFFERING, - NULL - ); - if (hDrive == INVALID_HANDLE_VALUE) { - printf("Open %s failed %d\n",devnam,GetLastError()); - return SS$_NOSUCHDEV; - } - if (LockVolume(hDrive) == FALSE) { - printf("LockVolume %s failed %d\n",devnam,GetLastError()); - return 72; - } - if (!GetDiskGeometry(hDrive,&Geometry)) { - printf("GetDiskGeometry %s failed %d\n",devnam,GetLastError()); - return 80; - } - /* If this is a 2048 byte sector device past C treat it as a CD... */ - - chantab[chan].device_type = 0; - if (Geometry.BytesPerSector == 2048 && toupper(*devnam) > 'C') { - sts = cd_initialize(); - if ((sts & 1) == 0) return sts; - chantab[chan].device_type = 1; - } - chantab[chan].sectorsize = Geometry.BytesPerSector; - info->sectors = (unsigned)(Geometry.Cylinders.QuadPart * Geometry.TracksPerCylinder * - Geometry.SectorsPerTrack); - - } else { - -#if defined(USE_WIN95) - /* W95 stuff */ - - - if (chantab[chan].device_name > 'C') { /* Assume above C are CDs.. */ - sts = cd_initialize(); - if ((sts & 1) == 0) return sts; - chantab[chan].device_type = 1; - chantab[chan].sectorsize = 2048; - } else { - DIOC_REGISTERS reg; - DEVICEPARAM deviceparam; - BOOL fResult; - DWORD cb; - chantab[chan].handle = hDrive = CreateFileA( - "\\\\.\\vwin32", - 0,0, - NULL, - 0, - FILE_FLAG_DELETE_ON_CLOSE, - NULL); - if (hDrive == INVALID_HANDLE_VALUE) { - printf("Open %s failed %d\n",devnam,GetLastError()); - return SS$_NOSUCHDEV; - } - reg.reg_EAX = 0x440d; - reg.reg_EBX = chantab[chan].device_name - 'A' + 1; - reg.reg_ECX = 0x084a; /* Lock volume */ - reg.reg_EDX = 0; - reg.reg_Flags = 0x0000; /* Permission */ - - fResult = DeviceIoControl(hDrive, - VWIN32_DIOC_DOS_IOCTL, - ®,sizeof(reg), - ®,sizeof(reg), - &cb,0); - - if (!fResult || (reg.reg_Flags & 0x0001)) { - printf("Volume lock failed (%d)\n",GetLastError()); - return SS$_DEVNOTALLOC; - } - reg.reg_EAX = 0x440d; - reg.reg_EBX = chantab[chan].device_name - 'A' + 1; - reg.reg_ECX = 0x0860; /* Get device parameters */ - reg.reg_EDX = (DWORD) & deviceparam; - reg.reg_Flags = 0x0001; /* set carry flag */ - - fResult = DeviceIoControl(hDrive, - VWIN32_DIOC_DOS_IOCTL, - ®,sizeof(reg), - ®,sizeof(reg), - &cb,0); - - if (!fResult || (reg.reg_Flags & 0x0001)) { - printf("Volume get parameters failed (%d)\n",GetLastError()); - return 8; - } - chantab[chan].sectorsize = deviceparam.sec_size; - } - info->sectors = 0; -#endif /* defined(USE_WIN95) */ - } - - chantab[chan].IoBuffer = VirtualAlloc(NULL, - chantab[chan].sectorsize + 304,MEM_COMMIT,PAGE_READWRITE); - chantab[chan].last_sector = 1000; - *chanptr = chan_count++; - info->status = 0; - info->sectorsize = chantab[chan].sectorsize; - init_count++; - return 1; - } else { - return SS$_IVCHAN; - } -} - - - - /* Read a physical sector... */ -unsigned phy_getsect(unsigned chan,unsigned sector,char **buffptr) +unsigned phy_getsect(unsigned chan,unsigned sector) { register unsigned sts = 1; if (sector != chantab[chan].last_sector) { - if (chantab[chan].device_type) { - sts = cd_read(sector,chantab[chan].IoBuffer); + if (chantab[chan].device_dtype >= 0) { + sts = aspi_read(chantab[chan].device_bus,chantab[chan].device_id,sector, + chantab[chan].sectorsize,chantab[chan].IoBuffer); } else { if (is_NT) { DWORD BytesRead = -1; /* NT Bytes read */ @@ -474,15 +420,161 @@ unsigned phy_getsect(unsigned chan,unsigned sector,char **buffptr) } if (sts & 1) { chantab[chan].last_sector = sector; - *buffptr = chantab[chan].IoBuffer; } return sts; } +/* Write a physical sector... */ + +unsigned phy_putsect(unsigned chan,unsigned sector) +{ + register unsigned sts = 1; + chantab[chan].last_sector = sector; + if (chantab[chan].device_dtype >= 0) { + sts = aspi_write(chantab[chan].device_bus,chantab[chan].device_id,sector, + chantab[chan].sectorsize,chantab[chan].IoBuffer); + } else { + if (is_NT) { + DWORD BytesRead = -1; /* NT Bytes written */ + SetFilePointer(chantab[chan].handle, + sector * chantab[chan].sectorsize,0,FILE_BEGIN); + if (!WriteFile(chantab[chan].handle,chantab[chan].IoBuffer, + chantab[chan].sectorsize,&BytesRead,NULL)) sts = SS$_PARITY; + } else { + sts = SS$_WRITLCK; /* Not implemented yet!! */ + } + } + return sts; +} + +#include "phyio.h" -/* Handle an I/O request ... need to read the approriate sectors to +unsigned init_count = 0; /* Some counters so we can report */ +unsigned read_count = 0; /* How often we get called */ +unsigned write_count = 0; + +void phyio_show(void) +{ + printf("PHYIO_SHOW Initializations: %d Reads: %d Writes: %d\n", + init_count,read_count,write_count); +} + + +/* Initialize device by opening it, locking it and getting it ready.. */ + +unsigned phyio_init(int devlen,char *devnam,unsigned *chanptr,struct phyio_info *info) +{ + unsigned sts = 1; + unsigned chan = chan_count; + if (chan < CHAN_MAX - 1 && devlen == 2 && + toupper(*devnam) >= 'A' && *(devnam + 1) == ':') { + HANDLE hDrive; + chantab[chan].device_status = 0; + chantab[chan].device_name = toupper(*devnam); + chantab[chan].device_dtype = -1; + + /* Use ASPI for devices past C... */ + + if (toupper(*devnam) > 'C') { + sts = aspi_initialize(&chantab[chan].device_dtype, + &chantab[chan].device_bus,&chantab[chan].device_id, + &chantab[chan].sectorsize); + if ((sts & 1) == 0) return sts; + } else { + + if (is_NT > 1) getsysversion(); + + /* NT stuff */ + + if (is_NT) { + char ntname[20]; + DISK_GEOMETRY Geometry; + sprintf(ntname,"\\\\.\\%s",devnam); + chantab[chan].handle = hDrive = CreateFile(ntname, + GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING,NULL); + if (hDrive == INVALID_HANDLE_VALUE) { + printf("Open %s failed %d\n",devnam,GetLastError()); + return SS$_NOSUCHDEV; + } + if (LockVolume(hDrive) == FALSE) { + printf("LockVolume %s failed %d\n",devnam,GetLastError()); + return 72; + } + if (!GetDiskGeometry(hDrive,&Geometry)) { + printf("GetDiskGeometry %s failed %d\n",devnam,GetLastError()); + return 80; + } + chantab[chan].sectorsize = Geometry.BytesPerSector; + info->sectors = Geometry.Cylinders.QuadPart * Geometry.TracksPerCylinder * + Geometry.SectorsPerTrack; + } else { + + /* W95 stuff */ + + DIOC_REGISTERS reg; + DEVICEPARAM deviceparam; + BOOL fResult; + DWORD cb; + chantab[chan].handle = hDrive = CreateFile("\\\\.\\vwin32", + 0,0,NULL,0,FILE_FLAG_DELETE_ON_CLOSE,NULL); + if (hDrive == INVALID_HANDLE_VALUE) { + printf("Open %s failed %d\n",devnam,GetLastError()); + return SS$_NOSUCHDEV; + } + reg.reg_EAX = 0x440d; + reg.reg_EBX = chantab[chan].device_name - 'A' + 1; + reg.reg_ECX = 0x084a; /* Lock volume */ + reg.reg_EDX = 0; + reg.reg_Flags = 0x0000; /* Permission */ + + fResult = DeviceIoControl(hDrive,VWIN32_DIOC_DOS_IOCTL, + ®,sizeof(reg),®,sizeof(reg),&cb,0); + + if (!fResult || (reg.reg_Flags & 0x0001)) { + printf("Volume lock failed (%d)\n",GetLastError()); + return SS$_DEVNOTALLOC; + } + reg.reg_EAX = 0x440d; + reg.reg_EBX = chantab[chan].device_name - 'A' + 1; + reg.reg_ECX = 0x0860; /* Get device parameters */ + reg.reg_EDX = (DWORD) & deviceparam; + reg.reg_Flags = 0x0001; /* set carry flag */ + + fResult = DeviceIoControl(hDrive, + VWIN32_DIOC_DOS_IOCTL, + ®,sizeof(reg), + ®,sizeof(reg), + &cb,0); + + if (!fResult || (reg.reg_Flags & 0x0001)) { + printf("Volume get parameters failed (%d)\n",GetLastError()); + return 8; + } + chantab[chan].sectorsize = deviceparam.sec_size; + } + info->sectors = 0; + } + + chantab[chan].IoBuffer = VirtualAlloc(NULL,chantab[chan].sectorsize, + MEM_COMMIT,PAGE_READWRITE); + chantab[chan].last_sector = 99999; + *chanptr = chan_count++; + info->status = 0; + info->sectorsize = chantab[chan].sectorsize; + init_count++; + return 1; + } else { + return SS$_IVCHAN; + } +} + + + + +/* Handle a read request ... need to read the approriate sectors to complete the request... */ unsigned phyio_read(unsigned chan,unsigned block,unsigned length,char *buffer) @@ -490,28 +582,69 @@ unsigned phyio_read(unsigned chan,unsigned block,unsigned length,char *buffer) register unsigned sts = 1; if (chan < chan_count) { - register unsigned sectorsize = chantab[chan].sectorsize; - register unsigned sectno = block / (sectorsize / 512); - register unsigned offset = (block - sectno * (sectorsize / 512)) * 512; + register unsigned sectblks = chantab[chan].sectorsize / 512; + register unsigned sectno = block / sectblks; + register unsigned offset = block % sectblks; + char *sectbuff = chantab[chan].IoBuffer; while (length > 0) { register unsigned transfer; - char *sectbuff; - if (((sts = phy_getsect(chan,sectno,§buff)) & 1) == 0) break; - transfer = sectorsize - offset; + transfer = (sectblks - offset) * 512; if (transfer > length) transfer = length; - memcpy(buffer,sectbuff + offset,transfer); + if (((sts = phy_getsect(chan,sectno)) & 1) == 0) break; + memcpy(buffer,sectbuff + (offset * 512),transfer); buffer += transfer; length -= transfer; sectno++; offset = 0; } + if (sts & 1) { + read_count++; + } else { + printf("PHYIO Error %d Block %d Length %d (ASPI: %x %x %x)\n", + sts,block,length,ASPI_status,ASPI_HaStat,ASPI_TargStat); + } + } else { sts = SS$_IVCHAN; } - if (sts & 1) { - read_count++; + return sts; +} + +/* Handle a write request ... need to read the approriate sectors to + complete the request... */ + +unsigned phyio_write(unsigned chan,unsigned block,unsigned length,char *buffer) +{ + register unsigned sts = 1; + + if (chan < chan_count) { + register unsigned sectblks = chantab[chan].sectorsize / 512; + register unsigned sectno = block / sectblks; + register unsigned offset = block % sectblks; + char *sectbuff = chantab[chan].IoBuffer; + while (length > 0) { + register unsigned transfer; + transfer = (sectblks - offset) * 512; + if (transfer > length) transfer = length; + if (transfer != sectblks * 512) { + if (((sts = phy_getsect(chan,sectno)) & 1) == 0) break; + } + memcpy(buffer,sectbuff + (offset * 512),transfer); + if (((sts = phy_putsect(chan,sectno)) & 1) == 0) break; + buffer += transfer; + length -= transfer; + sectno++; + offset = 0; + } + if (sts & 1) { + write_count++; + } else { + printf("PHYIO Error %d Block %d Length %d (ASPI: %x %x %x)\n", + sts,block,length,ASPI_status,ASPI_HaStat,ASPI_TargStat); + } + } else { - printf("PHYIO Error %d Block %d Length %d\n",sts,block,length); + sts = SS$_IVCHAN; } return sts; } diff --git a/extracters/ods2/phyunix.c b/extracters/ods2/phyunix.c new file mode 100644 index 0000000..d5bf8ca --- /dev/null +++ b/extracters/ods2/phyunix.c @@ -0,0 +1,102 @@ +/* PHYVMS.c v1.3 Physical I/O module for Unix */ + +/* + This is part of ODS2 written by Paul Nankervis, + email address: Paulnank@au1.ibm.com + + ODS2 is distributed freely for all members of the + VMS community to use. However all derived works + must maintain comments in their source to acknowledge + the contibution of the original author. +*/ + +/* + If the user mounts cd0 we open up /dev/cd0 for access. +*/ + +#include +#include +#include +#include + +#include "phyio.h" +#include "ssdef.h" + +#if defined(__digital__) && defined(__unix__) +#define DEV_PREFIX "/devices/rdisk/%s" +#else +#ifdef sun +#define DEV_PREFIX "/dev/dsk/%s" +#else +#define DEV_PREFIX "/dev/%s" +#endif +#endif + +unsigned init_count = 0; +unsigned read_count = 0; +unsigned write_count = 0; + +void phyio_show(void) +{ + printf("PHYIO_SHOW Initializations: %d Reads: %d Writes: %d\n", + init_count,read_count,write_count); +} + + +unsigned phyio_init(int devlen,char *devnam,unsigned *handle,struct phyio_info *info) +{ + int vmsfd; + char *cp,devbuf[200]; + init_count++; + info->status = 0; /* We don't know anything about this device! */ + info->sectors = 0; + info->sectorsize = 0; + sprintf(devbuf,DEV_PREFIX,devnam); + cp = strchr(devbuf,':'); + if (cp != NULL) *cp = '\0'; + vmsfd = open(devbuf,O_RDWR); + if (vmsfd < 0) vmsfd = open(devbuf,O_RDONLY); + if (vmsfd < 0) return SS$_NOSUCHDEV; + *handle = vmsfd; + return SS$_NORMAL; +} + + +unsigned phyio_close(unsigned handle) +{ + close(handle); + return SS$_NORMAL; +} + + +unsigned phyio_read(unsigned handle,unsigned block,unsigned length,char *buffer) +{ + int res; +#ifdef DEBUG + printf("Phyio read block: %d into %x (%d bytes)\n",block,buffer,length); +#endif + read_count++; + if ((res = lseek(handle,block*512,0)) < 0) { + perror("lseek "); + printf("lseek failed %d\n",res); + return SS$_PARITY; + } + if ((res = read(handle,buffer,length)) != length) { + perror("read "); + printf("read failed %d\n",res); + return SS$_PARITY; + } + return SS$_NORMAL; +} + + +unsigned phyio_write(unsigned handle,unsigned block,unsigned length,char *buffer) +{ +#ifdef DEBUG + printf("Phyio write block: %d from %x (%d bytes)\n",block,buffer,length); +#endif + write_count++; + if (lseek(handle,block*512,0) < 0) return SS$_PARITY; + if (write(handle,buffer,length) != length) return SS$_PARITY; + return SS$_NORMAL; +} diff --git a/extracters/ods2/phyvms.c b/extracters/ods2/phyvms.c index e4340cc..f88a1dc 100644 --- a/extracters/ods2/phyvms.c +++ b/extracters/ods2/phyvms.c @@ -1,4 +1,4 @@ -/* PHYVMS.C v1.2 Physical I/O module for VMS */ +/* PHYVMS.c v1.3 Physical I/O module for VMS */ /* This is part of ODS2 written by Paul Nankervis, @@ -16,12 +16,27 @@ even have different command sets depending on what mode they are called from! Sigh. */ +/* Modified by: + * + * 31-AUG-2001 01:04 Hunter Goatley + * + * Added checks to be sure device we're mounting is a + * disk and that it's already physically mounted at the + * DCL level, + * + */ #include #include #include #include #include +#include +#include +#include +#include +#include +#include #ifdef __GNUC__ unsigned sys$assign(); @@ -49,13 +64,64 @@ void phyio_show(void) unsigned phyio_init(int devlen,char *devnam,unsigned *handle,struct phyio_info *info) { struct dsc$descriptor devdsc; + unsigned long devclass, status; + char devname[65]; + unsigned long devchar; + unsigned long mntflags[2]; + struct ITMLST { + unsigned short length; + unsigned short itmcod; + void *buffer; + unsigned long *retlen; + } dvi_itmlst[4] = {{sizeof(devclass), DVI$_DEVCLASS, &devclass, 0}, + {sizeof(devname), DVI$_ALLDEVNAM, &devname, 0}, + {sizeof(devchar), DVI$_DEVCHAR, &devchar, 0}, + {0, 0, 0, 0}}, + mnt_itmlst[3] = {{0, MNT$_DEVNAM, 0, 0}, + {sizeof(mntflags), MNT$_FLAGS, &mntflags, 0}, + {0, 0, 0, 0}}; + devdsc.dsc$w_length = devlen; devdsc.dsc$a_pointer = devnam; + init_count++; info->status = 0; /* We don't know anything about this device! */ info->sectors = 0; info->sectorsize = 0; *handle = 0; + + /* Get some device information: device name, class, and mount status */ + status = sys$getdviw(0,0,&devdsc, &dvi_itmlst, 0,0,0,0); + if (status & 1) + { + if (devclass != DC$_DISK) /* If not a disk, return an error */ + return (SS$_IVDEVNAM); + + if (!(devchar & DEV$M_MNT)) + return (SS$_DEVNOTMOUNT); +#if 0 +/* + * This code will mount the disk if it's not already mounted. However, + * there's no good way to ensure we dismount a disk we mounted (no + * easy way to walk the list of devices at exit), so it's been #ifdefed + * out. If you enable it, the "mount" command will mount the disk, but + * it'll stay mounted by the process running ODS2, even after image exit. + */ + { + mnt_itmlst[0].length = strlen(devname); + mnt_itmlst[0].buffer = &devname; + mntflags[0] = MNT$M_FOREIGN | MNT$M_NOWRITE | MNT$M_NOASSIST | + MNT$M_NOMNTVER; + mntflags[1] = 0; + + status = sys$mount(&mnt_itmlst); + } +#endif + } + + if (!(status & 1)) + return (status); + return sys$assign(&devdsc,handle,0,0,0,0); } diff --git a/extracters/ods2/resource.h b/extracters/ods2/resource.h new file mode 100644 index 0000000..a725fff --- /dev/null +++ b/extracters/ods2/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by ODS2.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/extracters/ods2/rms.c b/extracters/ods2/rms.c index 38cc14d..839b094 100644 --- a/extracters/ods2/rms.c +++ b/extracters/ods2/rms.c @@ -1,4 +1,5 @@ -/* Rms.c v1.2 RMS components */ +/* check for cr - return terminator - update file length */ +/* RMS.c v1.3 RMS components */ /* This is part of ODS2 written by Paul Nankervis, @@ -24,11 +25,12 @@ #include #include #include + +#define NO_DOLLAR +#define RMS$INITIALIZE /* used by rms.h to create templates */ #include "descrip.h" #include "ssdef.h" #include "fibdef.h" - -#define RMS_INITIALIZE doit /* used by rms.h to create templates */ #include "rms.h" #include "access.h" #include "direct.h" @@ -130,7 +132,7 @@ int dircmp(unsigned keylen,void *key,void *node) register struct DIRCACHE *dirnode = (struct DIRCACHE *) node; register int cmp = keylen - dirnode->dirlen; if (cmp == 0) { - register unsigned len = keylen; + register int len = keylen; register char *keynam = (char *) key; register char *dirnam = dirnode->dirnam; while (len-- > 0) { @@ -154,8 +156,8 @@ unsigned dircache(struct VCB *vcb,char *dirnam,int dirlen,struct fiddef *dirid) dirid->fid$b_nmx = 0; return 1; } else { - unsigned create = 0; - dir = cachesearch((void *) &vcb->dircache,0,dirlen,dirnam,dircmp,&create); + unsigned sts; + dir = cache_find((void *) &vcb->dircache,dirlen,dirnam,&sts,dircmp,NULL); if (dir != NULL) { memcpy(dirid,&dir->dirid,sizeof(struct fiddef)); return 1; @@ -195,7 +197,7 @@ struct WCCDIR { int wcd_wcc; int wcd_prelen; unsigned short wcd_reslen; - struct dsc$descriptor wcd_serdsc; + struct dsc_descriptor wcd_serdsc; struct fiddef wcd_dirid; char wcd_sernam[1]; /* Must be last in structure */ }; /* Directory context */ @@ -244,7 +246,7 @@ unsigned do_search(struct FAB *fab,struct WCCFILE *wccfile) int sts; struct fibdef fibblk; struct WCCDIR *wcc; - struct dsc$descriptor fibdsc,resdsc; + struct dsc_descriptor fibdsc,resdsc; struct NAM *nam = fab->fab$l_nam; wcc = &wccfile->wcf_wcd; if (fab->fab$w_ifi != 0) return RMS$_IFI; @@ -254,15 +256,15 @@ unsigned do_search(struct FAB *fab,struct WCCFILE *wccfile) while ((wcc->wcd_status & STATUS_INIT) == 0 && wcc->wcd_next != NULL) { wcc = wcc->wcd_next; } - fibdsc.dsc$w_length = sizeof(struct fibdef); - fibdsc.dsc$a_pointer = (char *) &fibblk; + fibdsc.dsc_w_length = sizeof(struct fibdef); + fibdsc.dsc_a_pointer = (char *) &fibblk; while (1) { if ((wcc->wcd_status & STATUS_INIT) == 0 || wcc->wcd_wcc != 0) { wcc->wcd_status |= STATUS_INIT; - resdsc.dsc$w_length = 256 - wcc->wcd_prelen; - resdsc.dsc$a_pointer = wccfile->wcf_result + wcc->wcd_prelen; + resdsc.dsc_w_length = 256 - wcc->wcd_prelen; + resdsc.dsc_a_pointer = wccfile->wcf_result + wcc->wcd_prelen; memcpy(&fibblk.fib$w_did_num,&wcc->wcd_dirid,sizeof(struct fiddef)); - fibblk.fib$w_nmctl = 0; /* FIB$M_WILD; */ + fibblk.fib$w_nmctl = 0; /* FIB_M_WILD; */ fibblk.fib$l_acctl = 0; fibblk.fib$w_fid_num = 0; fibblk.fib$w_fid_seq = 0; @@ -270,7 +272,7 @@ unsigned do_search(struct FAB *fab,struct WCCFILE *wccfile) fibblk.fib$b_fid_nmx = 0; fibblk.fib$l_wcc = wcc->wcd_wcc; #ifdef DEBUG - wcc->wcd_sernam[wcc->wcd_serdsc.dsc$w_length] = '\0'; + wcc->wcd_sernam[wcc->wcd_serdsc.dsc_w_length] = '\0'; wccfile->wcf_result[wcc->wcd_prelen + wcc->wcd_reslen] = '\0'; printf("Ser: '%s' (%d,%d,%d) WCC: %d Prelen: %d '%s'\n",wcc->wcd_sernam, fibblk.fib$w_did_num | (fibblk.fib$b_did_nmx << 16), @@ -361,8 +363,8 @@ unsigned do_search(struct FAB *fab,struct WCCFILE *wccfile) } wcc->wcd_next = newwcc; memcpy(&newwcc->wcd_dirid,&wcc->wcd_dirid,sizeof(struct fiddef)); - newwcc->wcd_serdsc.dsc$w_length = 7; - newwcc->wcd_serdsc.dsc$a_pointer = newwcc->wcd_sernam; + newwcc->wcd_serdsc.dsc_w_length = 7; + newwcc->wcd_serdsc.dsc_a_pointer = newwcc->wcd_sernam; memcpy(newwcc->wcd_sernam,"*.DIR;1",7); newwcc->wcd_prelen = wcc->wcd_prelen; wcc = newwcc; @@ -447,6 +449,7 @@ unsigned do_parse(struct FAB *fab,struct WCCFILE **wccret) { wccfile = (struct WCCFILE *) malloc(sizeof(struct WCCFILE) + 256); if (wccfile == NULL) return SS$_INSFMEM; +memset(wccfile,0,sizeof(struct WCCFILE)+256); wccfile->wcf_fab = fab; wccfile->wcf_vcb = NULL; wccfile->wcf_fcb = NULL; @@ -610,8 +613,8 @@ unsigned do_parse(struct FAB *fab,struct WCCFILE **wccret) wcd->wcd_reslen = 0; memcpy(wcd->wcd_sernam,dirnam + dirsiz,seglen); memcpy(wcd->wcd_sernam + seglen,".DIR;1",7); - wcd->wcd_serdsc.dsc$w_length = seglen + 6; - wcd->wcd_serdsc.dsc$a_pointer = wcd->wcd_sernam; + wcd->wcd_serdsc.dsc_w_length = seglen + 6; + wcd->wcd_serdsc.dsc_a_pointer = wcd->wcd_sernam; wcd->wcd_prev = wcc; wcd->wcd_next = wcc->wcd_next; if (wcc->wcd_next != NULL) wcc->wcd_next->wcd_prev = wcd; @@ -623,19 +626,19 @@ unsigned do_parse(struct FAB *fab,struct WCCFILE **wccret) wcc->wcd_wcc = 0; wcc->wcd_status = 0; wcc->wcd_reslen = 0; - wcc->wcd_serdsc.dsc$w_length = fna_size[2] + fna_size[3] + fna_size[4]; - wcc->wcd_serdsc.dsc$a_pointer = wcc->wcd_sernam; + wcc->wcd_serdsc.dsc_w_length = fna_size[2] + fna_size[3] + fna_size[4]; + wcc->wcd_serdsc.dsc_a_pointer = wcc->wcd_sernam; memcpy(wcc->wcd_sernam,wccfile->wcf_result + fna_size[0] + fna_size[1], - wcc->wcd_serdsc.dsc$w_length); + wcc->wcd_serdsc.dsc_w_length); #ifdef DEBUG - wcc->wcd_sernam[wcc->wcd_serdsc.dsc$w_length] = '\0'; + wcc->wcd_sernam[wcc->wcd_serdsc.dsc_w_length] = '\0'; printf("Parse spec is %s\n",wccfile->wcf_wcd.wcd_sernam); for (dirsiz = 0; dirsiz < 5; dirsiz++) printf(" %d",fna_size[dirsiz]); printf("\n"); #endif } if (wccret != NULL) *wccret = wccfile; - if (nam != NULL) nam->nam$l_wcc = (int) wccfile; + if (nam != NULL) nam->nam$l_wcc = wccfile; return SS$_NORMAL; } @@ -652,15 +655,15 @@ unsigned sys_parse(struct FAB *fab) /* Function to set default directory (heck we can sneak in the device...) */ -unsigned sys_setddir(struct dsc$descriptor *newdir,unsigned short *oldlen, - struct dsc$descriptor *olddir) +unsigned sys_setddir(struct dsc_descriptor *newdir,unsigned short *oldlen, + struct dsc_descriptor *olddir) { unsigned sts = 1; if (oldlen != NULL) { int retlen = default_size[0] + default_size[1]; - if (retlen > olddir->dsc$w_length) retlen = olddir->dsc$w_length; + if (retlen > olddir->dsc_w_length) retlen = olddir->dsc_w_length; *oldlen = retlen; - memcpy(olddir->dsc$a_pointer,default_name,retlen); + memcpy(olddir->dsc_a_pointer,default_name,retlen); } if (newdir != NULL) { struct FAB fab = cc$rms_fab; @@ -669,8 +672,8 @@ unsigned sys_setddir(struct dsc$descriptor *newdir,unsigned short *oldlen, nam.nam$b_nop |= NAM$M_SYNCHK; nam.nam$b_ess = DEFAULT_SIZE; nam.nam$l_esa = default_buffer; - fab.fab$b_fns = newdir->dsc$w_length; - fab.fab$l_fna = newdir->dsc$a_pointer; + fab.fab$b_fns = newdir->dsc_w_length; + fab.fab$l_fna = newdir->dsc_a_pointer; sts = sys_parse(&fab); if (sts & 1) { if (nam.nam$b_name + nam.nam$b_type + nam.nam$b_ver > 2) return RMS$_DIR; @@ -710,9 +713,12 @@ unsigned sys_disconnect(struct RAB *rab) -#define IFI_MAX 10 +#define IFI_MAX 64 struct WCCFILE *ifi_table[] = { - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL }; @@ -720,157 +726,275 @@ struct WCCFILE *ifi_table[] = { unsigned sys_get(struct RAB *rab) { - char delim,*buffer,*output; - unsigned cpylen,reclen,block,blocks,offset,eofblk; - unsigned endflg,rfm,sts; + char *buffer,*recbuff; + unsigned block,blocks,offset; + unsigned cpylen,reclen; + unsigned delim,rfm,sts; struct VIOC *vioc; struct FCB *fcb = ifi_table[rab->rab$l_fab->fab$w_ifi]->wcf_fcb; - rfm = rab->rab$l_fab->fab$b_rfm; - if (rfm == FAB$C_STM || rfm == FAB$C_STMCR || rfm == FAB$C_STMLF) { - delim = 1; - if (rfm == FAB$C_STMLF) { - delim = '\n'; - } else { - if (rfm == FAB$C_STMCR) delim = '\r'; - } - reclen = rab->rab$w_usz; - } else { - delim = 0; - if (rfm == FAB$C_FIX) { + reclen = rab->rab$w_usz; + recbuff = rab->rab$l_ubf; + delim = 0; + switch (rfm = rab->rab$l_fab->fab$b_rfm) { + case FAB$C_STMLF: + delim = 1; + break; + case FAB$C_STMCR: + delim = 2; + break; + case FAB$C_STM: + delim = 3; + break; + case FAB$C_VFC: + reclen += rab->rab$l_fab->fab$b_fsz; + break; + case FAB$C_FIX: + if (reclen < rab->rab$l_fab->fab$w_mrs) return RMS$_RTB; reclen = rab->rab$l_fab->fab$w_mrs; - } + break; } - offset = rab->rab$w_rfa[2] + rab->rab$w_rsz; + offset = rab->rab$w_rfa[2] % 512; block = (rab->rab$w_rfa[1] << 16) + rab->rab$w_rfa[0]; - if (block == 0 && offset == 0) { - block = 1; - } else { - if (rab->rab$b_rac != RAB$C_RFA) { - if (delim) { - offset++; - } else { - if (rfm == FAB$C_VAR) { - offset += 2; - } else { - if (rfm == FAB$C_VFC) offset += 2 + rab->rab$l_fab->fab$b_fsz; + if (block == 0) block = 1; + + { + unsigned eofblk = VMSSWAP(fcb->head->fh2$w_recattr.fat$l_efblk); + if (block > eofblk || (block == eofblk && + offset >= VMSWORD(fcb->head->fh2$w_recattr.fat$w_ffbyte))) return RMS$_EOF; + } + + sts = accesschunk(fcb,block,&vioc,&buffer,&blocks,0); + if ((sts & 1) == 0) { + if (sts == SS$_ENDOFFILE) sts = RMS$_EOF; + return sts; + } + + if (rfm == FAB$C_VAR || rfm == FAB$C_VFC) { + vmsword *lenptr = (vmsword *) (buffer + offset); + reclen = VMSWORD(*lenptr); + offset += 2; + if (reclen > rab->rab$w_usz) { + sts = deaccesschunk(vioc,0,0,0); + return RMS$_RTB; + } + } + + cpylen = 0; + while (1) { + int dellen = 0; + int seglen = blocks * 512 - offset; + if (delim) { + if (delim >= 3) { + char *ptr = buffer + offset; + if (dellen == 1 && *ptr != '\n') { + if (cpylen >= reclen) { + seglen = 0; + sts = RMS$_RTB; + } else { + *recbuff++ = '\r'; + cpylen++; + } } - if (offset & 1) offset++; - if (rab->rab$l_fab->fab$b_rat & FAB$M_BLK) offset = (offset + 511) / 512 * 512; + while (seglen-- > 0) { + char ch = *ptr++; + if (ch == '\n' || ch == '\f' || ch == '\v') { + if (ch == '\n') { + dellen++; + } else { + dellen = 0; + } + delim = 99; + break; + } + dellen = 0; + if (ch == '\r') dellen = 1; + } + seglen = ptr - (buffer + offset) - dellen;; + } else { + char *ptr = buffer + offset; + char term = '\r'; + if (delim == 1) term = '\n'; + while (seglen-- > 0) { + if (*ptr++ == term) { + dellen = 1; + delim = 99; + break; + } + } + seglen = ptr - (buffer + offset) - dellen;; } - block += offset / 512; + } else { + if (seglen > reclen - cpylen) seglen = reclen - cpylen; + if (rfm == FAB$C_VFC && cpylen < rab->rab$l_fab->fab$b_fsz) { + unsigned fsz = rab->rab$l_fab->fab$b_fsz - cpylen; + if (fsz > seglen) fsz = seglen; + if (rab->rab$l_rhb) memcpy(rab->rab$l_rhb + cpylen,buffer + offset,fsz); + cpylen += fsz; + offset += fsz; + seglen -= fsz; + } + } + if (seglen) { + if (cpylen + seglen > reclen) { + seglen = reclen - cpylen; + sts = RMS$_RTB; + } + memcpy(recbuff,buffer + offset,seglen); + recbuff += seglen; + cpylen += seglen; + } + offset += seglen + dellen; + if ((offset & 1) && (rfm == FAB$C_VAR || rfm == FAB$C_VFC)) offset++; + deaccesschunk(vioc,0,0,1); + if ((sts & 1) == 0) return sts; + block += offset / 512; + offset %= 512; + if ((delim == 0 && cpylen >= reclen) || delim == 99) { + break; + } else { + sts = accesschunk(fcb,block,&vioc,&buffer,&blocks,0); + if ((sts & 1) == 0) { + if (sts == SS$_ENDOFFILE) sts = RMS$_EOF; + return sts; + } + offset = 0; } } + if (rfm == FAB$C_VFC) cpylen -= rab->rab$l_fab->fab$b_fsz; + rab->rab$w_rsz = cpylen; + rab->rab$w_rfa[0] = block & 0xffff; rab->rab$w_rfa[1] = block >> 16; - rab->rab$w_rfa[2] = offset = offset % 512; + rab->rab$w_rfa[2] = offset; + return sts; +} - eofblk = swapw(fcb->head->fh2$w_recattr.fat$l_efblk); - if (block > eofblk || (block == eofblk && - offset >= fcb->head->fh2$w_recattr.fat$w_ffbyte)) return RMS$_EOF; - sts = accesschunk(fcb,block,&vioc,&buffer,&blocks,0,NULL); +/* put for sequential files */ + +unsigned sys_put(struct RAB *rab) +{ + char *buffer,*recbuff; + unsigned block,blocks,offset; + unsigned cpylen,reclen; + unsigned delim,rfm,sts; + struct VIOC *vioc; + struct FCB *fcb = ifi_table[rab->rab$l_fab->fab$w_ifi]->wcf_fcb; + + reclen = rab->rab$w_rsz; + recbuff = rab->rab$l_rbf; + delim = 0; + switch (rfm = rab->rab$l_fab->fab$b_rfm) { + case FAB$C_STMLF: + if (reclen < 1) { + delim = 1; + } else { + if (recbuff[reclen] != '\n') delim = 1; + } + break; + case FAB$C_STMCR: + if (reclen < 1) { + delim = 2; + } else { + if (recbuff[reclen] != '\r') delim = 2; + } + break; + case FAB$C_STM: + if (reclen < 2) { + delim = 3; + } else { + if (recbuff[reclen-1] != '\r' || recbuff[reclen] != '\n') delim = 3; + } + break; + case FAB$C_VFC: + reclen += rab->rab$l_fab->fab$b_fsz; + break; + case FAB$C_FIX: + if (reclen != rab->rab$l_fab->fab$w_mrs) return RMS$_RSZ; + break; + } + + block = VMSSWAP(fcb->head->fh2$w_recattr.fat$l_efblk); + offset = VMSWORD(fcb->head->fh2$w_recattr.fat$w_ffbyte); + + sts = accesschunk(fcb,block,&vioc,&buffer,&blocks,1); if ((sts & 1) == 0) return sts; if (rfm == FAB$C_VAR || rfm == FAB$C_VFC) { - unsigned short *lenptr = (unsigned short *) (buffer + offset); - reclen = *lenptr; + vmsword *lenptr = (vmsword *) (buffer + offset); + *lenptr = VMSWORD(reclen); offset += 2; } -#ifdef DEBUG - printf("Block %d Offset %d Reclen %d Eofblk %d\n",block,offset,reclen,eofblk); -#endif - if (reclen > rab->rab$w_usz) { - sts = deaccesschunk(vioc,0,0); - return RMS$_RTB; - } - endflg = 0; - if (block + reclen / 512 >= eofblk) { - unsigned remaining = (eofblk - block) * 512 - offset + - fcb->head->fh2$w_recattr.fat$w_ffbyte; - if (remaining < reclen) { - reclen = remaining; - endflg = 1; - } - } cpylen = 0; - output = rab->rab$l_ubf; - while (cpylen < reclen) { - unsigned seglen = blocks * 512 - offset; + while (1) { + int seglen = blocks * 512 - offset; if (seglen > reclen - cpylen) seglen = reclen - cpylen; - if (delim) { - char *inptr = buffer + offset; - if (delim != 1) { - while (seglen-- > 0) { - char ch = *inptr++; - if (ch == delim) { - reclen = cpylen; - break; - } - if (cpylen++ < reclen) { - *output++ = ch; - } else { - sts = RMS$_RTB; - reclen = cpylen; - break; - } - } + if (rfm == FAB$C_VFC && cpylen < rab->rab$l_fab->fab$b_fsz) { + unsigned fsz = rab->rab$l_fab->fab$b_fsz - cpylen; + if (fsz > seglen) fsz = seglen; + if (rab->rab$l_rhb) { + memcpy(buffer + offset,rab->rab$l_rhb + cpylen,fsz); } else { - while (seglen-- > 0) { - char ch = *inptr++; - if (ch != 0 || cpylen > 0) { - if (ch == '\f' || ch == '\v' || ch == '\n' || ch == '\r') { - reclen = cpylen; - } else { - if (cpylen++ < reclen) { - *output++ = ch; - } else { - sts = RMS$_RTB; - reclen = cpylen; - break; - } - } - } - } - } - if (cpylen == reclen && endflg) break; - } else { - if (rfm == FAB$C_VFC) { - unsigned fsz = rab->rab$l_fab->fab$b_fsz; - if (fsz > seglen) fsz = seglen; - if (cpylen < fsz) { - fsz = fsz - cpylen; - if (rab->rab$l_rhb) memcpy(rab->rab$l_rhb + cpylen,buffer + offset,fsz); - cpylen += fsz; - offset += fsz; - seglen -= fsz; - } - } - memcpy(output,buffer + offset,seglen); - output += seglen; - cpylen += seglen; + memset(buffer + offset,0,fsz); + } + cpylen += fsz; + offset += fsz; + seglen -= fsz; } - if (cpylen < reclen) { - sts = deaccesschunk(vioc,0,0); - block += blocks; - if (block > eofblk) return RMS$_EOF; - sts = accesschunk(fcb,block,&vioc,&buffer,&blocks,0,NULL); + if (seglen) { + memcpy(buffer + offset,recbuff,seglen); + recbuff += seglen; + cpylen += seglen; + offset += seglen; + } + if (delim && offset < blocks * 512) { + offset++; + switch (delim) { + case 1: + *buffer = '\n'; + delim = 0; + break; + case 2: + *buffer = '\r'; + delim = 0; + break; + case 3: + *buffer = '\r'; + if (offset < blocks * 512) { + offset++; + *buffer = '\n'; + delim = 0; + } else { + delim = 2; + } + break; + } + } + sts = deaccesschunk(vioc,block,blocks,1); + if ((sts & 1) == 0) return sts; + block += blocks; + if (cpylen >= reclen && delim == 0) { + break; + } else { + sts = accesschunk(fcb,block,&vioc,&buffer,&blocks,1); if ((sts & 1) == 0) return sts; offset = 0; } } - if (rfm == FAB$C_VFC) { - rab->rab$w_rsz = cpylen - rab->rab$l_fab->fab$b_fsz;; - } else { - rab->rab$w_rsz = cpylen; - } - deaccesschunk(vioc,0,1); + if ((offset & 1) && (rfm == FAB$C_VAR || rfm == FAB$C_VFC)) offset++; + block += offset / 512; + offset %= 512; + fcb->head->fh2$w_recattr.fat$l_efblk = VMSSWAP(block); + fcb->head->fh2$w_recattr.fat$w_ffbyte = VMSWORD(offset); + rab->rab$w_rfa[0] = block & 0xffff; + rab->rab$w_rfa[1] = block >> 16; + rab->rab$w_rfa[2] = offset; return sts; } - /* display to fill fab & xabs with info from the file header... */ unsigned sys_display(struct FAB *fab) @@ -882,45 +1006,45 @@ unsigned sys_display(struct FAB *fab) struct IDENT *id = (struct IDENT *) (pp + head->fh2$b_idoffset); int ifi_no = fab->fab$w_ifi; if (ifi_no == 0 || ifi_no >= IFI_MAX) return RMS$_IFI; - fab->fab$l_alq = swapw(head->fh2$w_recattr.fat$l_hiblk); + fab->fab$l_alq = VMSSWAP(head->fh2$w_recattr.fat$l_hiblk); fab->fab$b_bks = head->fh2$w_recattr.fat$b_bktsize; - fab->fab$w_deq = head->fh2$w_recattr.fat$w_defext; + fab->fab$w_deq = VMSWORD(head->fh2$w_recattr.fat$w_defext); fab->fab$b_fsz = head->fh2$w_recattr.fat$b_vfcsize; - fab->fab$w_gbc = head->fh2$w_recattr.fat$w_gbc; - fab->fab$w_mrs = head->fh2$w_recattr.fat$w_maxrec; + fab->fab$w_gbc = VMSWORD(head->fh2$w_recattr.fat$w_gbc); + fab->fab$w_mrs = VMSWORD(head->fh2$w_recattr.fat$w_maxrec); fab->fab$b_org = head->fh2$w_recattr.fat$b_rtype & 0xf0; fab->fab$b_rfm = head->fh2$w_recattr.fat$b_rtype & 0x0f; fab->fab$b_rat = head->fh2$w_recattr.fat$b_rattrib; while (xab != NULL) { switch (xab->xab$b_cod) { case XAB$C_DAT: - memcpy(&xab->xab$q_bdt,&id->fi2$q_bakdate,sizeof(struct TIME)); - memcpy(&xab->xab$q_cdt,&id->fi2$q_credate,sizeof(struct TIME)); - memcpy(&xab->xab$q_edt,&id->fi2$q_expdate,sizeof(struct TIME)); - memcpy(&xab->xab$q_rdt,&id->fi2$q_revdate,sizeof(struct TIME)); + memcpy(&xab->xab$q_bdt,id->fi2$q_bakdate,sizeof(id->fi2$q_bakdate)); + memcpy(&xab->xab$q_cdt,id->fi2$q_credate,sizeof(id->fi2$q_credate)); + memcpy(&xab->xab$q_edt,id->fi2$q_expdate,sizeof(id->fi2$q_expdate)); + memcpy(&xab->xab$q_rdt,id->fi2$q_revdate,sizeof(id->fi2$q_revdate)); xab->xab$w_rvn = id->fi2$w_revision; break; case XAB$C_FHC:{ struct XABFHC *fhc = (struct XABFHC *) xab; fhc->xab$b_atr = head->fh2$w_recattr.fat$b_rattrib; fhc->xab$b_bkz = head->fh2$w_recattr.fat$b_bktsize; - fhc->xab$w_dxq = head->fh2$w_recattr.fat$w_defext; - fhc->xab$l_ebk = swapw(head->fh2$w_recattr.fat$l_efblk); - fhc->xab$w_ffb = head->fh2$w_recattr.fat$w_ffbyte; + fhc->xab$w_dxq = VMSWORD(head->fh2$w_recattr.fat$w_defext); + fhc->xab$l_ebk = VMSSWAP(head->fh2$w_recattr.fat$l_efblk); + fhc->xab$w_ffb = VMSWORD(head->fh2$w_recattr.fat$w_ffbyte); if (fhc->xab$l_ebk == 0) { fhc->xab$l_ebk = fab->fab$l_alq; if (fhc->xab$w_ffb == 0) fhc->xab$l_ebk++; } - fhc->xab$w_gbc = head->fh2$w_recattr.fat$w_gbc; - fhc->xab$l_hbk = swapw(head->fh2$w_recattr.fat$l_hiblk); + fhc->xab$w_gbc = VMSWORD(head->fh2$w_recattr.fat$w_gbc); + fhc->xab$l_hbk = VMSSWAP(head->fh2$w_recattr.fat$l_hiblk); fhc->xab$b_hsz = head->fh2$w_recattr.fat$b_vfcsize; - fhc->xab$w_lrl = head->fh2$w_recattr.fat$w_maxrec; - fhc->xab$w_verlimit = head->fh2$w_recattr.fat$w_versions; + fhc->xab$w_lrl = VMSWORD(head->fh2$w_recattr.fat$w_maxrec); + fhc->xab$w_verlimit = VMSWORD(head->fh2$w_recattr.fat$w_versions); } break; case XAB$C_PRO:{ struct XABPRO *pro = (struct XABPRO *) xab; - pro->xab$w_pro = head->fh2$w_fileprot; + pro->xab$w_pro = VMSWORD(head->fh2$w_fileprot); memcpy(&pro->xab$l_uic,&head->fh2$l_fileowner,4); } } @@ -981,10 +1105,13 @@ unsigned sys_open(struct FAB *fab) } else { sts = 1; } - if (sts & 1) sts = accessfile(wccfile->wcf_vcb,&wccfile->wcf_fid,&wccfile->wcf_fcb,0); + if (sts & 1) sts = accessfile(wccfile->wcf_vcb,&wccfile->wcf_fid,&wccfile->wcf_fcb, + fab->fab$b_fac & (FAB$M_PUT | FAB$M_UPD)); if (sts & 1) { + struct HEAD *head = wccfile->wcf_fcb->head; ifi_table[ifi_no] = wccfile; fab->fab$w_ifi = ifi_no; + if (head->fh2$w_recattr.fat$b_rtype == 0) head->fh2$w_recattr.fat$b_rtype = FAB$C_STMLF; sys_display(fab); } if (wcc_flag && ((sts & 1) == 0)) { @@ -1025,11 +1152,11 @@ unsigned sys_erase(struct FAB *fab) } if (sts & 1) { struct fibdef fibblk; - struct dsc$descriptor fibdsc,serdsc; - fibdsc.dsc$w_length = sizeof(struct fibdef); - fibdsc.dsc$a_pointer = (char *) &fibblk; - serdsc.dsc$w_length = wccfile->wcf_wcd.wcd_reslen; - serdsc.dsc$a_pointer = wccfile->wcf_result + wccfile->wcf_wcd.wcd_prelen; + struct dsc_descriptor fibdsc,serdsc; + fibdsc.dsc_w_length = sizeof(struct fibdef); + fibdsc.dsc_a_pointer = (char *) &fibblk; + serdsc.dsc_w_length = wccfile->wcf_wcd.wcd_reslen; + serdsc.dsc_a_pointer = wccfile->wcf_result + wccfile->wcf_wcd.wcd_prelen; memcpy(&fibblk.fib$w_did_num,&wccfile->wcf_wcd.wcd_dirid,sizeof(struct fiddef)); fibblk.fib$w_nmctl = 0; fibblk.fib$l_acctl = 0; @@ -1039,7 +1166,11 @@ unsigned sys_erase(struct FAB *fab) fibblk.fib$b_fid_nmx = 0; fibblk.fib$l_wcc = 0; sts = direct(wccfile->wcf_vcb,&fibdsc,&serdsc,NULL,NULL,1); - if (sts & 1) sts = accesserase(wccfile->wcf_vcb,&wccfile->wcf_fid); + if (sts & 1) { + sts = accesserase(wccfile->wcf_vcb,&wccfile->wcf_fid); + } else { + printf("Direct status is %d\n",sts); + } } if (wcc_flag) { cleanup_wcf(wccfile); @@ -1047,3 +1178,72 @@ unsigned sys_erase(struct FAB *fab) } return sts; } + + +unsigned sys_create(struct FAB *fab) +{ + unsigned sts; + int ifi_no = 1; + int wcc_flag = 0; + struct WCCFILE *wccfile = NULL; + struct NAM *nam = fab->fab$l_nam; + if (fab->fab$w_ifi != 0) return RMS$_IFI; + while (ifi_table[ifi_no] != NULL && ifi_no < IFI_MAX) ifi_no++; + if (ifi_no >= IFI_MAX) return RMS$_IFI; + if (nam != NULL) { + wccfile = (struct WCCFILE *) fab->fab$l_nam->nam$l_wcc; + } + if (wccfile == NULL) { + sts = do_parse(fab,&wccfile); + if (sts & 1) { + wcc_flag = 1; + if (wccfile->wcf_status & STATUS_WILDCARD) { + sts = RMS$_WLD; + } else { + sts = do_search(fab,wccfile); + if (sts == RMS$_FNF) sts = 1; + } + } + } else { + sts = 1; + } + if (sts & 1) { + struct fibdef fibblk; + struct dsc_descriptor fibdsc,serdsc; + fibdsc.dsc_w_length = sizeof(struct fibdef); + fibdsc.dsc_a_pointer = (char *) &fibblk; + serdsc.dsc_w_length = wccfile->wcf_wcd.wcd_reslen; + serdsc.dsc_a_pointer = wccfile->wcf_result + wccfile->wcf_wcd.wcd_prelen; + memcpy(&fibblk.fib$w_did_num,&wccfile->wcf_wcd.wcd_dirid,sizeof(struct fiddef)); + fibblk.fib$w_nmctl = 0; + fibblk.fib$l_acctl = 0; + fibblk.fib$w_did_num = 11; + fibblk.fib$w_did_seq = 1; + fibblk.fib$b_did_rvn = 0; + fibblk.fib$b_did_nmx = 0; + fibblk.fib$l_wcc = 0; + sts = update_create(wccfile->wcf_vcb,(struct fiddef *)&fibblk.fib$w_did_num, + "TEST.FILE;1",(struct fiddef *)&fibblk.fib$w_fid_num,&wccfile->wcf_fcb); + if (sts & 1) + sts = direct(wccfile->wcf_vcb,&fibdsc, + &wccfile->wcf_wcd.wcd_serdsc,NULL,NULL,2); + if (sts & 1) { + sts = update_extend(wccfile->wcf_fcb,100,0); + ifi_table[ifi_no] = wccfile; + fab->fab$w_ifi = ifi_no; + } + } + cleanup_wcf(wccfile); + if (nam != NULL) nam->nam$l_wcc = 0; + return sts; +} + +unsigned sys_extend(struct FAB *fab) +{ + int sts; + int ifi_no = fab->fab$w_ifi; + if (ifi_no < 1 || ifi_no >= IFI_MAX) return RMS$_IFI; + sts = update_extend(ifi_table[ifi_no]->wcf_fcb, + fab->fab$l_alq - ifi_table[ifi_no]->wcf_fcb->hiblock,0); + return sts; +} diff --git a/extracters/ods2/rms.h b/extracters/ods2/rms.h index 4f875ff..e875532 100644 --- a/extracters/ods2/rms.h +++ b/extracters/ods2/rms.h @@ -1,4 +1,4 @@ -/* RMS.H v1.2 RMS routine definitions */ +/* RMS.h v1.3 RMS routine definitions */ /* This is part of ODS2 written by Paul Nankervis, @@ -10,14 +10,7 @@ the contibution of the original author. */ -/* If not using GNU C on VMS use real RMS structures :-)... - otherwise define minimum subset to meet our requirements */ - -#if defined(VMS) && !defined(__GNUC__) - -#include - -#else +#ifndef RMS$_RTB #include "vmstime.h" @@ -33,6 +26,7 @@ #define RMS$_IFI 99684 #define RMS$_NAM 99804 #define RMS$_RSS 99988 +#define RMS$_RSZ 100004 #define RMS$_WLD 100164 #define RMS$_DNF 114762 @@ -44,20 +38,21 @@ #define XAB$C_FHC 29 #define XAB$C_PRO 19 + struct XABDAT { void *xab$l_nxt; int xab$b_cod; int xab$w_rvn; - struct TIME xab$q_bdt; - struct TIME xab$q_cdt; - struct TIME xab$q_edt; - struct TIME xab$q_rdt; + VMSTIME xab$q_bdt; + VMSTIME xab$q_cdt; + VMSTIME xab$q_edt; + VMSTIME xab$q_rdt; }; -#ifdef RMS_INITIALIZE +#ifdef RMS$INITIALIZE struct XABDAT cc$rms_xabdat = {NULL,XAB$C_DAT,0, - {{0,0,0,0,0,0,0,0}}, {{0,0,0,0,0,0,0,0}}, - {{0,0,0,0,0,0,0,0}}, {{0,0,0,0,0,0,0,0}}}; + VMSTIME_ZERO, VMSTIME_ZERO, + VMSTIME_ZERO, VMSTIME_ZERO}; #else extern struct XABDAT cc$rms_xabdat; #endif @@ -79,7 +74,7 @@ struct XABFHC { int xab$w_verlimit; }; -#ifdef RMS_INITIALIZE +#ifdef RMS$INITIALIZE struct XABFHC cc$rms_xabfhc = {NULL,XAB$C_FHC,0,0,0,0,0,0,0,0,0,0}; #else extern struct XABFHC cc$rms_xabfhc; @@ -94,12 +89,14 @@ struct XABPRO { int xab$l_uic; }; -#ifdef RMS_INITIALIZE +#ifdef RMS$INITIALIZE struct XABPRO cc$rms_xabpro = {NULL,XAB$C_PRO,0,0}; #else extern struct XABPRO cc$rms_xabpro; #endif + + #define NAM$M_WILDCARD 0x100 struct NAM { @@ -127,17 +124,18 @@ struct NAM { char *nam$l_type; int nam$b_ver; char *nam$l_ver; - int nam$l_wcc; + void *nam$l_wcc; int nam$b_nop; int nam$l_fnb; }; -#ifdef RMS_INITIALIZE +#ifdef RMS$INITIALIZE struct NAM cc$rms_nam = {0,0,0,0,0,0,0,0,0,0,0,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0,0,0}; #else extern struct NAM cc$rms_nam; #endif + #define RAB$C_SEQ 0 #define RAB$C_RFA 2 @@ -145,19 +143,21 @@ struct RAB { struct FAB *rab$l_fab; char *rab$l_ubf; char *rab$l_rhb; + char *rab$l_rbf; unsigned rab$w_usz; unsigned rab$w_rsz; int rab$b_rac; unsigned short rab$w_rfa[3]; }; -#ifdef RMS_INITIALIZE -struct RAB cc$rms_rab = {NULL,NULL,NULL,0,0,0,{0,0,0}}; +#ifdef RMS$INITIALIZE +struct RAB cc$rms_rab = {NULL,NULL,NULL,NULL,0,0,0,{0,0,0}}; #else extern struct RAB cc$rms_rab; #endif + #define FAB$C_SEQ 0 #define FAB$C_REL 16 #define FAB$C_IDX 32 @@ -168,6 +168,15 @@ extern struct RAB cc$rms_rab; #define FAB$M_PRN 4 #define FAB$M_BLK 8 +#define FAB$M_PUT 0x1 +#define FAB$M_GET 0x2 +#define FAB$M_DEL 0x4 +#define FAB$M_UPD 0x8 +#define FAB$M_TRN 0x10 +#define FAB$M_BIO 0x20 +#define FAB$M_BRO 0x40 +#define FAB$M_EXE 0x80 + #define FAB$C_UDF 0 #define FAB$C_FIX 1 #define FAB$C_VAR 2 @@ -193,17 +202,18 @@ struct FAB { int fab$b_org; int fab$b_rat; int fab$b_rfm; + int fab$b_fac; void *fab$l_xab; }; -#ifdef RMS_INITIALIZE -struct FAB cc$rms_fab = {NULL,0,NULL,NULL,0,0,0,0,0,0,0,0,0,0,0,0,NULL}; +#ifdef RMS$INITIALIZE +struct FAB cc$rms_fab = {NULL,0,NULL,NULL,0,0,0,0,0,0,0,0,0,0,0,0,0,NULL}; #else extern struct FAB cc$rms_fab; #endif -#endif +#ifndef NO_DOLLAR #define sys$search sys_search #define sys$parse sys_parse #define sys$setddir sys_setddir @@ -213,17 +223,22 @@ extern struct FAB cc$rms_fab; #define sys$display sys_display #define sys$close sys_close #define sys$open sys_open +#define sys$create sys_create #define sys$erase sys_erase - +#endif unsigned sys_search(struct FAB *fab); unsigned sys_parse(struct FAB *fab); unsigned sys_connect(struct RAB *rab); unsigned sys_disconnect(struct RAB *rab); unsigned sys_get(struct RAB *rab); +unsigned sys_put(struct RAB *rab); unsigned sys_display(struct FAB *fab); unsigned sys_close(struct FAB *fab); unsigned sys_open(struct FAB *fab); +unsigned sys_create(struct FAB *fab); unsigned sys_erase(struct FAB *fab); -unsigned sys_setddir(struct dsc$descriptor *newdir,unsigned short *oldlen, - struct dsc$descriptor *olddir); +unsigned sys_extend(struct FAB *fab); +unsigned sys_setddir(struct dsc_descriptor *newdir,unsigned short *oldlen, + struct dsc_descriptor *olddir); +#endif diff --git a/extracters/ods2/scsidefs.h b/extracters/ods2/scsidefs.h new file mode 100644 index 0000000..d8a1005 --- /dev/null +++ b/extracters/ods2/scsidefs.h @@ -0,0 +1,271 @@ +//*************************************************************************** +// +// Name: SCSIDEFS.H +// +// Description: SCSI definitions ('C' Language) +// +//*************************************************************************** + +//*************************************************************************** +// %%% TARGET STATUS VALUES %%% +//*************************************************************************** +#define STATUS_GOOD 0x00 // Status Good +#define STATUS_CHKCOND 0x02 // Check Condition +#define STATUS_CONDMET 0x04 // Condition Met +#define STATUS_BUSY 0x08 // Busy +#define STATUS_INTERM 0x10 // Intermediate +#define STATUS_INTCDMET 0x14 // Intermediate-condition met +#define STATUS_RESCONF 0x18 // Reservation conflict +#define STATUS_COMTERM 0x22 // Command Terminated +#define STATUS_QFULL 0x28 // Queue full + +//*************************************************************************** +// %%% SCSI MISCELLANEOUS EQUATES %%% +//*************************************************************************** +#define MAXLUN 7 // Maximum Logical Unit Id +#define MAXTARG 7 // Maximum Target Id +#define MAX_SCSI_LUNS 64 // Maximum Number of SCSI LUNs +#define MAX_NUM_HA 8 // Maximum Number of SCSI HA's + +//--------------------------------------------------------------------------- +// +// %%% SCSI COMMAND OPCODES %%% +// +//--------------------------------------------------------------------------- +//*************************************************************************** +// %%% Commands for all Device Types %%% +//*************************************************************************** +#define SCSI_CHANGE_DEF 0x40 // Change Definition (Optional) +#define SCSI_COMPARE 0x39 // Compare (O) +#define SCSI_COPY 0x18 // Copy (O) +#define SCSI_COP_VERIFY 0x3A // Copy and Verify (O) +#define SCSI_INQUIRY 0x12 // Inquiry (MANDATORY) +#define SCSI_LOG_SELECT 0x4C // Log Select (O) +#define SCSI_LOG_SENSE 0x4D // Log Sense (O) +#define SCSI_MODE_SEL6 0x15 // Mode Select 6-byte (Device Specific) +#define SCSI_MODE_SEL10 0x55 // Mode Select 10-byte (Device Specific) +#define SCSI_MODE_SEN6 0x1A // Mode Sense 6-byte (Device Specific) +#define SCSI_MODE_SEN10 0x5A // Mode Sense 10-byte (Device Specific) +#define SCSI_READ_BUFF 0x3C // Read Buffer (O) +#define SCSI_REQ_SENSE 0x03 // Request Sense (MANDATORY) +#define SCSI_SEND_DIAG 0x1D // Send Diagnostic (O) +#define SCSI_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY) +#define SCSI_WRITE_BUFF 0x3B // Write Buffer (O) + +//*************************************************************************** +// %%% Commands Unique to Direct Access Devices %%% +//*************************************************************************** +#define SCSI_COMPARE 0x39 // Compare (O) +#define SCSI_FORMAT 0x04 // Format Unit (MANDATORY) +#define SCSI_LCK_UN_CAC 0x36 // Lock Unlock Cache (O) +#define SCSI_PREFETCH 0x34 // Prefetch (O) +#define SCSI_MED_REMOVL 0x1E // Prevent/Allow medium Removal (O) +#define SCSI_READ6 0x08 // Read 6-byte (MANDATORY) +#define SCSI_READ10 0x28 // Read 10-byte (MANDATORY) +#define SCSI_RD_CAPAC 0x25 // Read Capacity (MANDATORY) +#define SCSI_RD_DEFECT 0x37 // Read Defect Data (O) +#define SCSI_READ_LONG 0x3E // Read Long (O) +#define SCSI_REASS_BLK 0x07 // Reassign Blocks (O) +#define SCSI_RCV_DIAG 0x1C // Receive Diagnostic Results (O) +#define SCSI_RELEASE 0x17 // Release Unit (MANDATORY) +#define SCSI_REZERO 0x01 // Rezero Unit (O) +#define SCSI_SRCH_DAT_E 0x31 // Search Data Equal (O) +#define SCSI_SRCH_DAT_H 0x30 // Search Data High (O) +#define SCSI_SRCH_DAT_L 0x32 // Search Data Low (O) +#define SCSI_SEEK6 0x0B // Seek 6-Byte (O) +#define SCSI_SEEK10 0x2B // Seek 10-Byte (O) +#define SCSI_SEND_DIAG 0x1D // Send Diagnostics (MANDATORY) +#define SCSI_SET_LIMIT 0x33 // Set Limits (O) +#define SCSI_START_STP 0x1B // Start/Stop Unit (O) +#define SCSI_SYNC_CACHE 0x35 // Synchronize Cache (O) +#define SCSI_VERIFY 0x2F // Verify (O) +#define SCSI_WRITE6 0x0A // Write 6-Byte (MANDATORY) +#define SCSI_WRITE10 0x2A // Write 10-Byte (MANDATORY) +#define SCSI_WRT_VERIFY 0x2E // Write and Verify (O) +#define SCSI_WRITE_LONG 0x3F // Write Long (O) +#define SCSI_WRITE_SAME 0x41 // Write Same (O) + +//*************************************************************************** +// %%% Commands Unique to Sequential Access Devices %%% +//*************************************************************************** +#define SCSI_ERASE 0x19 // Erase (MANDATORY) +#define SCSI_LOAD_UN 0x1b // Load/Unload (O) +#define SCSI_LOCATE 0x2B // Locate (O) +#define SCSI_RD_BLK_LIM 0x05 // Read Block Limits (MANDATORY) +#define SCSI_READ_POS 0x34 // Read Position (O) +#define SCSI_READ_REV 0x0F // Read Reverse (O) +#define SCSI_REC_BF_DAT 0x14 // Recover Buffer Data (O) +#define SCSI_RESERVE 0x16 // Reserve Unit (MANDATORY) +#define SCSI_REWIND 0x01 // Rewind (MANDATORY) +#define SCSI_SPACE 0x11 // Space (MANDATORY) +#define SCSI_VERIFY_T 0x13 // Verify (Tape) (O) +#define SCSI_WRT_FILE 0x10 // Write Filemarks (MANDATORY) + +//*************************************************************************** +// %%% Commands Unique to Printer Devices %%% +//*************************************************************************** +#define SCSI_PRINT 0x0A // Print (MANDATORY) +#define SCSI_SLEW_PNT 0x0B // Slew and Print (O) +#define SCSI_STOP_PNT 0x1B // Stop Print (O) +#define SCSI_SYNC_BUFF 0x10 // Synchronize Buffer (O) + +//*************************************************************************** +// %%% Commands Unique to Processor Devices %%% +//*************************************************************************** +#define SCSI_RECEIVE 0x08 // Receive (O) +#define SCSI_SEND 0x0A // Send (O) + +//*************************************************************************** +// %%% Commands Unique to Write-Once Devices %%% +//*************************************************************************** +#define SCSI_MEDIUM_SCN 0x38 // Medium Scan (O) +#define SCSI_SRCHDATE10 0x31 // Search Data Equal 10-Byte (O) +#define SCSI_SRCHDATE12 0xB1 // Search Data Equal 12-Byte (O) +#define SCSI_SRCHDATH10 0x30 // Search Data High 10-Byte (O) +#define SCSI_SRCHDATH12 0xB0 // Search Data High 12-Byte (O) +#define SCSI_SRCHDATL10 0x32 // Search Data Low 10-Byte (O) +#define SCSI_SRCHDATL12 0xB2 // Search Data Low 12-Byte (O) +#define SCSI_SET_LIM_10 0x33 // Set Limits 10-Byte (O) +#define SCSI_SET_LIM_12 0xB3 // Set Limits 10-Byte (O) +#define SCSI_VERIFY10 0x2F // Verify 10-Byte (O) +#define SCSI_VERIFY12 0xAF // Verify 12-Byte (O) +#define SCSI_WRITE12 0xAA // Write 12-Byte (O) +#define SCSI_WRT_VER10 0x2E // Write and Verify 10-Byte (O) +#define SCSI_WRT_VER12 0xAE // Write and Verify 12-Byte (O) + +//*************************************************************************** +// %%% Commands Unique to CD-ROM Devices %%% +//*************************************************************************** +#define SCSI_PLAYAUD_10 0x45 // Play Audio 10-Byte (O) +#define SCSI_PLAYAUD_12 0xA5 // Play Audio 12-Byte 12-Byte (O) +#define SCSI_PLAYAUDMSF 0x47 // Play Audio MSF (O) +#define SCSI_PLAYA_TKIN 0x48 // Play Audio Track/Index (O) +#define SCSI_PLYTKREL10 0x49 // Play Track Relative 10-Byte (O) +#define SCSI_PLYTKREL12 0xA9 // Play Track Relative 12-Byte (O) +#define SCSI_READCDCAP 0x25 // Read CD-ROM Capacity (MANDATORY) +#define SCSI_READHEADER 0x44 // Read Header (O) +#define SCSI_SUBCHANNEL 0x42 // Read Subchannel (O) +#define SCSI_READ_TOC 0x43 // Read TOC (O) + +//*************************************************************************** +// %%% Commands Unique to Scanner Devices %%% +//*************************************************************************** +#define SCSI_GETDBSTAT 0x34 // Get Data Buffer Status (O) +#define SCSI_GETWINDOW 0x25 // Get Window (O) +#define SCSI_OBJECTPOS 0x31 // Object Postion (O) +#define SCSI_SCAN 0x1B // Scan (O) +#define SCSI_SETWINDOW 0x24 // Set Window (MANDATORY) + +//*************************************************************************** +// %%% Commands Unique to Optical Memory Devices %%% +//*************************************************************************** +#define SCSI_UpdateBlk 0x3D // Update Block (O) + +//*************************************************************************** +// %%% Commands Unique to Medium Changer Devices %%% +//*************************************************************************** +#define SCSI_EXCHMEDIUM 0xA6 // Exchange Medium (O) +#define SCSI_INITELSTAT 0x07 // Initialize Element Status (O) +#define SCSI_POSTOELEM 0x2B // Position to Element (O) +#define SCSI_REQ_VE_ADD 0xB5 // Request Volume Element Address (O) +#define SCSI_SENDVOLTAG 0xB6 // Send Volume Tag (O) + +//*************************************************************************** +// %%% Commands Unique to Communication Devices %%% +//*************************************************************************** +#define SCSI_GET_MSG_6 0x08 // Get Message 6-Byte (MANDATORY) +#define SCSI_GET_MSG_10 0x28 // Get Message 10-Byte (O) +#define SCSI_GET_MSG_12 0xA8 // Get Message 12-Byte (O) +#define SCSI_SND_MSG_6 0x0A // Send Message 6-Byte (MANDATORY) +#define SCSI_SND_MSG_10 0x2A // Send Message 10-Byte (O) +#define SCSI_SND_MSG_12 0xAA // Send Message 12-Byte (O) +//--------------------------------------------------------------------------- +// +// %%% END OF SCSI COMMAND OPCODES %%% +// +//--------------------------------------------------------------------------- + +//*************************************************************************** +// %%% Request Sense Data Format %%% +//*************************************************************************** +typedef struct { + BYTE ErrorCode; // Error Code (70H or 71H) + BYTE SegmentNum; // Number of current segment descriptor + BYTE SenseKey; // Sense Key(See bit definitions too) + BYTE InfoByte0; // Information MSB + BYTE InfoByte1; // Information MID + BYTE InfoByte2; // Information MID + BYTE InfoByte3; // Information LSB + BYTE AddSenLen; // Additional Sense Length + BYTE ComSpecInf0; // Command Specific Information MSB + BYTE ComSpecInf1; // Command Specific Information MID + BYTE ComSpecInf2; // Command Specific Information MID + BYTE ComSpecInf3; // Command Specific Information LSB + BYTE AddSenseCode; // Additional Sense Code + BYTE AddSenQual; // Additional Sense Code Qualifier + BYTE FieldRepUCode; // Field Replaceable Unit Code + BYTE SenKeySpec15; // Sense Key Specific 15th byte + BYTE SenKeySpec16; // Sense Key Specific 16th byte + BYTE SenKeySpec17; // Sense Key Specific 17th byte + BYTE AddSenseBytes; // Additional Sense Bytes +} SENSE_DATA_FMT; + +//*************************************************************************** +// %%% REQUEST SENSE ERROR CODE %%% +//*************************************************************************** +#define SERROR_CURRENT 0x70 // Current Errors +#define SERROR_DEFERED 0x71 // Deferred Errors + +//*************************************************************************** +// %%% REQUEST SENSE BIT DEFINITIONS %%% +//*************************************************************************** +#define SENSE_VALID 0x80 // Byte 0 Bit 7 +#define SENSE_FILEMRK 0x80 // Byte 2 Bit 7 +#define SENSE_EOM 0x40 // Byte 2 Bit 6 +#define SENSE_ILI 0x20 // Byte 2 Bit 5 + +//*************************************************************************** +// %%% REQUEST SENSE SENSE KEY DEFINITIONS %%% +//*************************************************************************** +#define KEY_NOSENSE 0x00 // No Sense +#define KEY_RECERROR 0x01 // Recovered Error +#define KEY_NOTREADY 0x02 // Not Ready +#define KEY_MEDIUMERR 0x03 // Medium Error +#define KEY_HARDERROR 0x04 // Hardware Error +#define KEY_ILLGLREQ 0x05 // Illegal Request +#define KEY_UNITATT 0x06 // Unit Attention +#define KEY_DATAPROT 0x07 // Data Protect +#define KEY_BLANKCHK 0x08 // Blank Check +#define KEY_VENDSPEC 0x09 // Vendor Specific +#define KEY_COPYABORT 0x0A // Copy Abort +#define KEY_EQUAL 0x0C // Equal (Search) +#define KEY_VOLOVRFLW 0x0D // Volume Overflow +#define KEY_MISCOMP 0x0E // Miscompare (Search) +#define KEY_RESERVED 0x0F // Reserved + +//*************************************************************************** +// %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%% +//*************************************************************************** +#define DTYPE_DASD 0x00 // Disk Device +#define DTYPE_SEQD 0x01 // Tape Device +#define DTYPE_PRNT 0x02 // Printer +#define DTYPE_PROC 0x03 // Processor +#define DTYPE_WORM 0x04 // Write-once read-multiple +#define DTYPE_CROM 0x05 // CD-ROM device +#define DTYPE_SCAN 0x06 // Scanner device +#define DTYPE_OPTI 0x07 // Optical memory device +#define DTYPE_JUKE 0x08 // Medium Changer device +#define DTYPE_COMM 0x09 // Communications device +#define DTYPE_RESL 0x0A // Reserved (low) +#define DTYPE_RESH 0x1E // Reserved (high) +#define DTYPE_UNKNOWN 0x1F // Unknown or no device type + +//*************************************************************************** +// %%% ANSI APPROVED VERSION DEFINITIONS %%% +//*************************************************************************** +#define ANSI_MAYBE 0x0 // Device may or may not be ANSI approved stand +#define ANSI_SCSI1 0x1 // Device complies to ANSI X3.131-1986 (SCSI-1) +#define ANSI_SCSI2 0x2 // Device complies to SCSI-2 +#define ANSI_RESLO 0x3 // Reserved (low) +#define ANSI_RESHI 0x7 // Reserved (high) + diff --git a/extracters/ods2/ssdef.h b/extracters/ods2/ssdef.h index e1bedf2..bea9a23 100644 --- a/extracters/ods2/ssdef.h +++ b/extracters/ods2/ssdef.h @@ -1,4 +1,4 @@ -/* Ssdef.h v1.2 System status definitions */ +/* Ssdef.h v1.3 System status definitions */ /* This is part of ODS2 written by Paul Nankervis, @@ -10,17 +10,13 @@ the contibution of the original author. */ - -#ifdef VMS - -#include - -#else +#ifndef SS$_NORMAL #define SS$_NORMAL 1 #define SS$_WASCLR 1 #define SS$_WASSET 9 #define SS$_ABORT 44 +#define SS$_DEVMOUNT 108 #define SS$_DEVNOTMOUNT 124 #define SS$_ILLEFC 236 #define SS$_INSFMEM 292 @@ -29,11 +25,15 @@ #define SS$_DUPLICATE 148 #define SS$_BADPARAM 20 #define SS$_IVCHAN 316 +#define SS$_IVDEVNAM 324 #define SS$_NOIOCHAN 436 #define SS$_PARITY 500 #define SS$_WRITLCK 604 +#define SS$_BADIRECTORY 2088 +#define SS$_DEVICEFULL 2128 #define SS$_DEVNOTALLOC 2136 #define SS$_DUPFILENAME 2152 +#define SS$_FILESEQCHK 2232 #define SS$_NOSUCHDEV 2312 #define SS$_NOSUCHFILE 2320 #define SS$_BADFILENAME 2072 @@ -41,8 +41,10 @@ #define SS$_ENDOFFILE 2160 #define SS$_FILELOCKED 2216 #define SS$_NOMOREFILES 2352 +#define SS$_ITEMNOTFOUND 2640 #define SS$_NOSUCHVOL 3882 #define SS$_NOTINSTALL 8212 #define SS$_DEVNOTDISM 8628 +#define SS$_UNSUPVOLSET 9908 #endif diff --git a/extracters/ods2/update.c b/extracters/ods2/update.c new file mode 100644 index 0000000..6e47013 --- /dev/null +++ b/extracters/ods2/update.c @@ -0,0 +1,677 @@ +#include +#include +#include +#include +#include "ssdef.h" +#include "access.h" + +unsigned deaccesshead(struct VIOC *vioc,struct HEAD *head,unsigned idxblk); +unsigned accesshead(struct VCB *vcb,struct fiddef *fid,unsigned seg_num, + struct VIOC **vioc,struct HEAD **headbuff, + unsigned *retidxblk,unsigned wrtflg); +unsigned getwindow(struct FCB * fcb,unsigned vbn,struct VCBDEV **devptr, + unsigned *phyblk,unsigned *phylen,struct fiddef *hdrfid, + unsigned *hdrseq); +struct VCBDEV *rvn_to_dev(struct VCB *vcb,unsigned rvn); + + + +/* Bitmaps get accesses in 'WORK_UNITs' which can be an integer + on a little endian machine but must be a byte on a big endian system */ + +#ifdef BIG_ENDIAN +#define WORK_UNIT unsigned char +#define WORK_MASK 0xff +#else +#define WORK_UNIT unsigned int +#define WORK_MASK 0xffffffff +#endif +#define WORK_BITS (sizeof(WORK_UNIT) * 8) + +/* update_freecount() to read the device cluster bitmap and compute + the number of un-used clusters */ + +unsigned update_freecount(struct VCBDEV *vcbdev,unsigned *retcount) +{ + register unsigned sts; + register unsigned free_clusters = 0; + register unsigned map_block, map_end = (vcbdev->max_cluster + 4095) / 4096 + 2; + for (map_block = 2; map_block < map_end; ) { + struct VIOC *vioc; + unsigned blkcount; + WORK_UNIT *bitmap,*work_ptr; + register unsigned work_count; + sts = accesschunk(vcbdev->mapfcb,map_block, &vioc,(char **) &bitmap,&blkcount,0); + if (!(sts & 1)) return sts; + if (blkcount > map_end - map_block) blkcount = map_end - map_block + 1; + work_ptr = bitmap; + work_count = blkcount * 512 / sizeof(WORK_UNIT); + do { + register WORK_UNIT work_val = *work_ptr++; + if (work_val == WORK_MASK) { + free_clusters += WORK_BITS; + } else { + while (work_val != 0) { + if (work_val & 1) free_clusters++; + work_val = work_val >> 1; + } + } + } while (--work_count > 0); + sts = deaccesschunk(vioc,0,0,1); + if (!(sts & 1)) return sts; + map_block += blkcount; + } + *retcount = free_clusters; + return sts; +} + +/* bitmap_modify() will either set or release a block of bits in the + device cluster bitmap */ + +unsigned bitmap_modify(struct VCBDEV *vcbdev,unsigned cluster,unsigned count, + unsigned release_flag) +{ + register unsigned sts; + register unsigned clust_count = count; + register unsigned map_block = cluster / 4096 + 2; + register unsigned block_offset = cluster % 4096; + if (clust_count < 1) return SS$_BADPARAM; + if (cluster + clust_count > vcbdev->max_cluster + 1) return SS$_BADPARAM; + do { + struct VIOC *vioc; + unsigned blkcount; + WORK_UNIT *bitmap; + register WORK_UNIT *work_ptr; + register unsigned work_count; + sts = accesschunk(vcbdev->mapfcb,map_block,&vioc,(char **) &bitmap,&blkcount,1); + if (!(sts & 1)) return sts; + work_ptr = bitmap + block_offset / WORK_BITS; + if (block_offset % WORK_BITS) { + register unsigned bit_no = block_offset % WORK_BITS; + register WORK_UNIT bit_mask = WORK_MASK; + if (bit_no + clust_count < WORK_BITS) { + bit_mask = bit_mask >> (WORK_BITS - clust_count); + clust_count = 0; + } else { + clust_count -= WORK_BITS - bit_no; + } + bit_mask = bit_mask << bit_no; + if (release_flag) { + *work_ptr++ |= bit_mask; + } else { + *work_ptr++ &= ~bit_mask; + } + block_offset += WORK_BITS - bit_no; + } + work_count = (blkcount * 4096 - block_offset) / WORK_BITS; + if (work_count > clust_count / WORK_BITS) { + work_count = clust_count / WORK_BITS; + block_offset = 1; + } else { + block_offset = 0; + } + clust_count -= work_count * WORK_BITS; + if (release_flag) { + while (clust_count-- > 0) { + *work_ptr++ = WORK_MASK; + } + } else { + while (work_count-- > 0) { + *work_ptr++ = 0; + } + } + if (clust_count != 0 && block_offset) { + register WORK_UNIT bit_mask = WORK_MASK >> (WORK_BITS - clust_count); + if (release_flag) { + *work_ptr++ |= bit_mask; + } else { + *work_ptr++ &= ~bit_mask; + } + clust_count = 0; + } + sts = deaccesschunk(vioc,map_block,blkcount,1); + if (!(sts & 1)) return sts; + map_block += blkcount; + block_offset = 0; + } while (clust_count != 0); + return sts; +} + +/* bitmap_search() is a routine to find a pool of free clusters in the + device cluster bitmap */ + +unsigned bitmap_search(struct VCBDEV *vcbdev,unsigned *position,unsigned *count) +{ + register unsigned sts; + register unsigned map_block,block_offset; + register unsigned search_words,needed; + register unsigned run = 0,cluster; + register unsigned best_run = 0,best_cluster = 0; + needed = *count; + if (needed < 1 || needed > vcbdev->max_cluster + 1) return SS$_BADPARAM; + cluster = *position; + if (cluster + *count > vcbdev->max_cluster + 1) cluster = 0; + map_block = cluster / 4096 + 2; + block_offset = cluster % 4096; + cluster = cluster - (cluster % WORK_BITS); + search_words = vcbdev->max_cluster / WORK_BITS; + do { + struct VIOC *vioc; + unsigned blkcount; + WORK_UNIT *bitmap; + register WORK_UNIT *work_ptr, work_val; + register unsigned work_count; + sts = accesschunk(vcbdev->mapfcb,map_block,&vioc,(char **) &bitmap,&blkcount,1); + if ((sts & 1) == 0) return sts; + work_ptr = bitmap + block_offset / WORK_BITS; + work_val = *work_ptr++; + if (block_offset % WORK_BITS) { + work_val = work_val && (WORK_MASK << block_offset % WORK_BITS); + } + work_count = (blkcount * 4096 - block_offset) / WORK_BITS; + if (work_count > search_words) work_count = search_words; + search_words -= work_count; + do { + if (work_val == WORK_MASK) { + run += WORK_BITS; + } else { + register unsigned bit_no = 0; + while (work_val != 0) { + if (work_val & 1) { + run++; + } else { + if (run > best_run) { + best_run = run; + best_cluster = cluster + bit_no; + } + run = 0; + } + work_val = work_val >> 1; + bit_no++; + } + if (bit_no < WORK_BITS) { + if (run > best_run) { + best_run = run; + best_cluster = cluster + bit_no; + } + run = 0; + } + } + cluster += WORK_BITS; + if (work_count-- > 0) { + work_val = *work_ptr++; + } else { + break; + } + } while (best_run < needed); + deaccesschunk(vioc,map_block,0,1); + if ((sts & 1) == 0) break; + map_block += blkcount; + block_offset = 0; + } while (best_run < needed && search_words != 0); + if (best_run > needed) best_run = needed; + *count = best_run; + *position = best_cluster; + return sts; +} + +/* headmap_clear() will release a header from the indexf.sys file header + bitmap */ + +unsigned headmap_clear(struct VCBDEV *vcbdev,unsigned head_no) +{ + WORK_UNIT *bitmap; + struct VIOC *vioc; + register unsigned sts; + register unsigned map_block = head_no / 4096 + vcbdev->home.hm2$w_cluster * 4 + 1; + if (head_no < 10) return 0; + sts = accesschunk(vcbdev->idxfcb,map_block,&vioc,(char **) &bitmap,NULL,1); + if (sts & 1) { + bitmap[(head_no % 4096) / WORK_BITS] &= ~(1 << (head_no % WORK_BITS)); + sts = deaccesschunk(vioc,map_block,1,1); + } + return sts; +} + +/* update_findhead() will locate a free header from indexf.sys */ + +unsigned update_findhead(struct VCBDEV *vcbdev,unsigned *rethead_no, + struct VIOC **retvioc,struct HEAD **headbuff, + unsigned *retidxblk) +{ + unsigned head_no = 0; + register unsigned sts; + do { + struct VIOC *vioc; + int modify_flag = 0; + unsigned blkcount; + WORK_UNIT *bitmap,*work_ptr; + register unsigned map_block,work_count; + map_block = head_no / 4096 + vcbdev->home.hm2$w_cluster * 4 + 1; + sts = accesschunk(vcbdev->idxfcb,map_block, + &vioc,(char **) &bitmap,&blkcount,1); + if ((sts & 1) == 0) return sts; + work_count = (head_no % 4096) / WORK_BITS; + work_ptr = bitmap + work_count; + work_count = blkcount * 512 / WORK_BITS - work_count; + do { + register WORK_UNIT work_val = *work_ptr; + if (work_val == WORK_MASK) { + head_no += WORK_BITS; + } else { + register unsigned bit_no = 0; + for (bit_no = 0; bit_no < WORK_BITS; bit_no++) { + if ((work_val & (1 << bit_no)) == 0) { + register unsigned idxblk = head_no + + VMSWORD(vcbdev->home.hm2$w_ibmapvbn) + + VMSWORD(vcbdev->home.hm2$w_ibmapsize); + sts = accesschunk(vcbdev->idxfcb,idxblk,retvioc,(char **) headbuff,NULL,1); + if (sts & 1) { + *work_ptr |= 1 << bit_no; + modify_flag = 1; + if ((*headbuff)->fh2$w_checksum != 0 || (*headbuff)->fh2$w_fid.fid$w_num != 0 || + VMSLONG((*headbuff)->fh2$l_filechar) & FH2$M_MARKDEL == 0) { + sts = deaccesschunk(*retvioc,0,0,0); + } else { + *rethead_no = head_no + 1; + *retidxblk = idxblk; + deaccesschunk(vioc,map_block,blkcount,modify_flag); + return SS$_NORMAL; + } + } + } + head_no++; + } + } + work_ptr++; + } while (--work_count != 0); + deaccesschunk(vioc,map_block,blkcount,modify_flag); + if ((sts & 1) == 0) break; + } while (head_no < VMSLONG(vcbdev->home.hm2$l_maxfiles)); + return sts; +} + +unsigned update_addhead(struct VCB *vcb,char *filename,struct fiddef *back, + unsigned seg_num,struct fiddef *fid, + struct VIOC **vioc,struct HEAD **rethead, + unsigned *idxblk) +{ + register unsigned free_space = 0; + register unsigned device,rvn,sts; + unsigned head_no; + struct IDENT *id; + struct HEAD *head; + struct VCBDEV *vcbdev = NULL; + for (device = 0; device < vcb->devices; device++) { + if (vcb->vcbdev[device].dev != NULL) { + if (vcb->vcbdev[device].free_clusters > free_space) { + free_space = vcb->vcbdev[device].free_clusters; + vcbdev = &vcb->vcbdev[device]; + rvn = device; + } + } + } + if (vcbdev == NULL) return SS$_DEVICEFULL; + + sts = update_findhead(vcbdev,&head_no,vioc,&head,idxblk); + if (!(sts & 1)) return sts; + printf("Header %d index %d rvn %d\n",head_no,idxblk,rvn); + fid->fid$w_num = head_no; + fid->fid$w_seq = ++head->fh2$w_fid.fid$w_seq; + if (fid->fid$w_seq == 0) fid->fid$w_seq = 1; + if (rvn > 0) { + fid->fid$b_rvn = rvn + 1; + } else { + fid->fid$b_rvn = 0; + } + fid->fid$b_nmx = head_no >> 16; + memset(head,0,512); + head->fh2$b_idoffset = 40; + head->fh2$b_mpoffset = 100; + head->fh2$b_acoffset = 255; + head->fh2$b_rsoffset = 255; + head->fh2$w_seg_num = seg_num; + head->fh2$w_struclev = 513; + head->fh2$l_fileowner.uic$w_mem = 4; + head->fh2$l_fileowner.uic$w_grp = 1; + fid_copy(&head->fh2$w_fid,fid,0); + if (back != NULL) fid_copy(&head->fh2$w_backlink,back,0); + id = (struct IDENT *) ((unsigned short *) head + 40); + memset(id->fi2$t_filenamext,' ',66); + if (strlen(filename) < 20) { + memset(id->fi2$t_filename,' ',20); + memcpy(id->fi2$t_filename,filename,strlen(filename)); + } else { + memcpy(id->fi2$t_filename,filename,20); + memcpy(id->fi2$t_filenamext,filename+20,strlen(filename+20)); + } + id->fi2$w_revision = 1; + sys_gettim(id->fi2$q_credate); + memcpy(id->fi2$q_revdate,id->fi2$q_credate,sizeof(id->fi2$q_credate)); + memcpy(id->fi2$q_expdate,id->fi2$q_credate,sizeof(id->fi2$q_credate)); + head->fh2$w_recattr.fat$l_efblk = VMSSWAP(1); + { + unsigned short check = checksum((vmsword *) head); + head->fh2$w_checksum = VMSWORD(check); + } + return 1; +} + +/* update_create() will create a new file... */ + +unsigned update_create(struct VCB *vcb,struct fiddef *did,char *filename, + struct fiddef *fid,struct FCB **fcb) +{ + struct VIOC *vioc; + struct HEAD *head; + unsigned idxblk; + register unsigned sts; + sts = update_addhead(vcb,filename,did,0,fid,&vioc,&head,&idxblk); + if (!(sts & 1)) return sts; + sts = deaccesshead(vioc,head,idxblk); + if (sts & 1 && fcb != NULL) { + sts = accessfile(vcb,fid,fcb,1); + } + printf("(%d,%d,%d) %d\n",fid->fid$w_num,fid->fid$w_seq,fid->fid$b_rvn,sts); + return sts; +} + +unsigned update_extend(struct FCB *fcb,unsigned blocks,unsigned contig) +{ + register unsigned sts; + struct VCBDEV *vcbdev; + struct VIOC *vioc; + struct HEAD *head; + unsigned headvbn; + struct fiddef hdrfid; + unsigned hdrseq; + unsigned start_pos = 0; + unsigned block_count = blocks; + if (block_count < 1) return 0; + if ((fcb->status & FCB_WRITE) == 0) return SS$_WRITLCK; + if (fcb->hiblock > 0) { + unsigned mapblk,maplen; + sts = getwindow(fcb,fcb->hiblock,&vcbdev,&mapblk,&maplen,&hdrfid,&hdrseq); + if ((sts & 1) == 0) return sts; + start_pos = mapblk + 1; + if (hdrseq != 0) { + sts = accesshead(fcb->vcb,&hdrfid,hdrseq,&vioc,&head,&headvbn,1); + if ((sts & 1) == 0) return sts; + } else { + head = fcb->head; + vioc = NULL; + } + } else { + head = fcb->head; + vioc = NULL; + start_pos = 0; /* filenum * 3 /indexfsize * volumesize; */ + } + if (vioc == NULL) vcbdev = rvn_to_dev(fcb->vcb,fcb->rvn); + if (vcbdev->free_clusters == 0 || head->fh2$b_map_inuse + 4 >= + head->fh2$b_acoffset - head->fh2$b_mpoffset) { + struct VIOC *nvioc; + struct HEAD *nhead; + unsigned nidxblk; + sts = update_addhead(fcb->vcb,"",&head->fh2$w_fid,head->fh2$w_seg_num+1, + &head->fh2$w_ext_fid,&nvioc,&nhead,&nidxblk); + if (!(sts & 1)) return sts; + if (vioc != NULL) deaccesshead(vioc,head,headvbn); + vioc = nvioc; + head = nhead; + headvbn = nidxblk; + vcbdev = rvn_to_dev(fcb->vcb,head->fh2$w_fid.fid$b_rvn); + } + sts = bitmap_search(vcbdev,&start_pos,&block_count); + printf("Update_extend %d %d\n",start_pos,block_count); + if (sts & 1) { + if (block_count < 1 || contig && block_count * vcbdev->clustersize < blocks) { + sts = SS$_DEVICEFULL; + } else { + register unsigned short *mp; + mp = (unsigned short *) head + head->fh2$b_mpoffset + head->fh2$b_map_inuse; + *mp++ = (3 << 14) | ((block_count *vcbdev->clustersize - 1) >> 16); + *mp++ = (block_count * vcbdev->clustersize - 1) & 0xffff; + *mp++ = (start_pos * vcbdev->clustersize) & 0xffff; + *mp++ = (start_pos * vcbdev->clustersize) >> 16; + head->fh2$b_map_inuse += 4; + fcb->hiblock += block_count * vcbdev->clustersize; + fcb->head->fh2$w_recattr.fat$l_hiblk = VMSSWAP(fcb->hiblock * vcbdev->clustersize); + sts = bitmap_modify(vcbdev,start_pos,block_count,0); + } + } + if (vioc != NULL) deaccesshead(vioc,head,headvbn); + return sts; +} + + + + +/* This routine has bugs and does NOT work properly yet!!!! +It may be something simple but I haven't had time to look... +So DON'T use mount/write!!! */ + +unsigned deallocfile(struct FCB *fcb) +{ + register unsigned sts = 1; + /* + First mark all file clusters as free in BITMAP.SYS + */ + register unsigned vbn = 1; + while (vbn <= fcb->hiblock) { + register unsigned sts; + unsigned phyblk,phylen; + struct VCBDEV *vcbdev; + sts = getwindow(fcb,vbn,&vcbdev,&phyblk,&phylen,NULL,NULL); + if ((sts & 1) == 0) break; + + sts = bitmap_modify(vcbdev,phyblk,phylen,1); + if ((sts & 1) == 0) break; + } + /* + Now reset file header bit map in INDEXF.SYS and + update each of the file headers... + */ + { + unsigned rvn = fcb->rvn; + unsigned headvbn = fcb->headvbn; + struct HEAD *head = fcb->head; + struct VIOC *headvioc = fcb->headvioc; + do { + unsigned ext_seg_num = 0; + struct fiddef extfid; + register struct VCBDEV *vcbdev; + unsigned *bitmap; + struct VIOC *vioc; + register unsigned filenum = (head->fh2$w_fid.fid$b_nmx << 16) + + head->fh2$w_fid.fid$w_num - 1; + register unsigned idxblk; + vcbdev = rvn_to_dev(fcb->vcb,rvn); + if (vcbdev == NULL) break; + idxblk = filenum / 4096 + + vcbdev->home.hm2$w_cluster * 4 + 1; + sts = accesschunk(vcbdev->idxfcb,idxblk,&vioc, + (char **) &bitmap,NULL,1); + if (sts & 1) { + bitmap[(filenum % 4096) / WORK_BITS] &= + ~(1 << (filenum % WORK_BITS)); + sts = deaccesschunk(vioc,idxblk,1,1); + } else { + break; + } + head->fh2$w_fid.fid$w_num = 0; + head->fh2$w_fid.fid$b_rvn = 0; + head->fh2$w_fid.fid$b_nmx = 0; + head->fh2$w_checksum = 0; + ext_seg_num++; + memcpy(&extfid,&fcb->head->fh2$w_ext_fid,sizeof(struct fiddef)); + sts = deaccesshead(headvioc,NULL,headvbn); + if ((sts & 1) == 0) break; + if (extfid.fid$b_rvn == 0) { + extfid.fid$b_rvn = rvn; + } else { + rvn = extfid.fid$b_rvn; + } + if (extfid.fid$w_num != 0 || extfid.fid$b_nmx != 0) { + sts = accesshead(fcb->vcb,&extfid,ext_seg_num,&headvioc,&head,&headvbn,1); + if ((sts & 1) == 0) break; + } else { + break; + } + } while (1); + if (sts & 1) { + fcb->headvioc = NULL; + cache_untouch(&fcb->cache,0); + cache_delete(&fcb->cache); + } + } + return sts; +} + + + +/* accesserase: delete a file... */ + +unsigned accesserase(struct VCB * vcb,struct fiddef * fid) +{ + struct FCB *fcb; + register int sts; + sts = accessfile(vcb,fid,&fcb,1); + if (sts & 1) { + fcb->head->fh2$l_filechar |= FH2$M_MARKDEL; + printf("Accesserase ... \n"); + sts = deaccessfile(fcb); + } + return sts; +} + + + + +#ifdef EXTEND +unsigned extend(struct FCB *fcb,unsigned blocks) +{ + register unsigned sts; + struct VCBDEV *vcbdev; + unsigned clusterno; + unsigned extended = 0; + if ((fcb->status & FCB_WRITE) == 0) return SS$_WRITLCK; + if (fcb->hiblock > 0) { + unsigned phyblk,phylen; + sts = getwindow(fcb,fcb->hiblock,&vcbdev,&phyblk,&phylen,NULL,NULL); + clusterno = (phyblk + 1) / vcbdev->home.hm2$w_cluster; + if ((sts & 1) == 0) return sts; + } else { + vcbdev = fcb->vcb->vcbdev; + clusterno = 0; /* filenum * 3 /indexfsize * volumesize; */ + } + while (extended < blocks) { + unsigned *bitmap,blkcount; + struct VIOC *vioc; + register unsigned clustalq = 0; + register unsigned clustersz = vcbdev->home.hm2$w_cluster; + sts = accesschunk(vcbdev->mapfcb,clusterno / 4096 + 2, + &vioc,(char **) &bitmap,&blkcount,1); + if ((sts & 1) == 0) return sts; + do { + register unsigned wordno = (clusterno % 4096) / WORK_BITS; + register unsigned wordval = bitmap[wordno]; + if (wordval == 0xffff) { + if (clustalq) break; + clusterno = (clusterno % WORK_BITS) * + WORK_BITS + 1; + } else { + register unsigned bitno = clusterno % WORK_BITS; + do { + if (wordval & (1 << bitno)) { + if (clustalq) break; + } else { + clustalq++; + wordval |= 1 << bitno; + } + clusterno++; + if (clustalq >= (extended - blocks)) break; + } while (++bitno < WORK_BITS); + if (clustalq) { + bitmap[wordno] = wordval; + if (bitno < WORK_BITS) break; + } + } + } while (++wordno < blkcount * 512 / sizeof(unsigned)); + mp = (unsigned word *) fcb->head + fcb->head->fh2$b_mpoffset; + *mp++ = (3 << 14) | (clustalq >> 16); + *mp++ = clustalq & 0xff; + *mp++ = clustno & 0xff; + *clusertize + * mp++ = clustno << 16; + fcb->head->fh2$b_map_inuse + 4; + fcb->hiblock += clustalq; + fcb->head.fh2$w_recattr.fat$l_hiblk[0] = fcb->hiblock >> 16; + fcb->head.fh2$w_recattr.fat$l_hiblk[1] = fcb->hiblock & 0xff; + sts = deaccesschunk(vioc,clusterno / 4096 + 2,blkcount,1); + /* code to append clusterno:clustalq to map */ + } +} +#endif + + + +#ifdef EXTEND + +unsigned access_create(struct VCB * vcb,struct FCB ** fcbadd,unsigned blocks) { + register struct FCB *fcb; + struct fiddef fid; + unsigned create = sizeof(struct FCB); + if (wrtflg && ((vcb->status & VCB_WRITE) == 0)) return SS$_WRITLCK; + + sts = headmap_search(struct VCBDEV * vcbdev,struct fiddef * fid, + struct VIOC ** vioc,struct HEAD ** headbuff,unsigned *retidxblk,) { + fcb = cachesearch((void *) &vcb->fcb,filenum,0,NULL,NULL,&create); + if (fcb == NULL) return SS$_INSFMEM; + /* If not found make one... */ + if (create == 0) { + fcb->cache.objtype = CACHETYPE_DEV; + fcb->rvn = fid->fid_b_rvn; + if (fcb->rvn == 0 && vcb->devices > 1) fcb->rvn = 1; + fcb->vcb = vcb; + fcb->wcb = NULL; + fcb->headvbn = 0; + fcb->vioc = NULL; + fcb->headvioc = NULL; + fcb->cache.objmanager = fcbmanager; + } + if (wrtflg) { + if (fcb->headvioc != NULL && (fcb->cache.status & CACHE_WRITE) == 0) { + deaccesshead(fcb->headvioc,NULL,0); + fcb->headvioc = NULL; + } + fcb->cache.status |= CACHE_WRITE; + } + if (fcb->headvioc == NULL) { + register unsigned sts; + if (vcb->idxboot != NULL) { + *fcbadd = fcb; + fcb->hiblock = 32767; /* guess at indexf.sys file size */ + fcb->highwater = 0; + fcb->head = vcb->idxboot; /* Load bootup header */ + } + sts = accesshead(vcb,fid,0,&fcb->headvioc,&fcb->head,&fcb->headvbn,wrtflg); + if (sts & 1) { + fcb->hiblock = VMSSWAP(fcb->head->fh2$w_recattr.fat$l_hiblk); + if (fcb->head->fh2$b_idoffset > 39) { + fcb->highwater = fcb->head->fh2$l_highwater; + } else { + fcb->highwater = 0; + } + } else { + printf("Accessfile status %d\n",sts); + fcb->cache.objmanager = NULL; + cacheuntouch(&fcb->cache,0,0); + cachefree(&fcb->cache); + return sts; + } + } + *fcbadd = fcb; + return SS$_NORMAL; + } +#endif + diff --git a/extracters/ods2/vmstime.c b/extracters/ods2/vmstime.c index 2caf8b5..78015c7 100644 --- a/extracters/ods2/vmstime.c +++ b/extracters/ods2/vmstime.c @@ -1,30 +1,44 @@ /* - VMSTIME.C v1.2 + Vmstime.c v1.6A - Author: Paul Nankervis + Author: Paul Nankervis - V1.2 - cleanup to stop compiler warnings + 1.4 Changed declarations NOT to define DOLLAR identifiers + unless DOLLAR is defined (some compilers can't handle $'s!) + 1.4A Changed default DOLLAR handling to include DOLLAR + identifers unless NO_DOLLAR is defined + (ie #ifdef DOLLAR to #ifndef NO_DOLLAR) + 1.5 Added 64 bit support and cvt_internal routines + 1.6 Change addx, subx and compare to use larger integers + 1.6A Fixed endian problems in addx/subx - Please send bug reports or requests for enhancement - or improvement via email to: PaulNank@au1.ibm.com + Please send bug reports or requests for enhancement + or improvement via email to: PaulNank@au1.ibm.com - This module contains versions of the VMS time routines - sys$numtim(), sys$asctim() and friends... They are - intended to be compatible with the routines of the same - name on a VMS system (so descriptors feature regularly!) + This module contains versions of the VMS time routines + sys$numtim(), sys$asctim() and friends... They are + intended to be compatible with the routines of the same + name on a VMS system (so descriptors feature regularly!) - This code relies on being able to manipluate day numbers - and times using 32 bit arithmetic to crack a VMS quadword - byte by byte. If your C compiler doesn't have 32 bit int - fields give up now! On a 64 bit systems this code could - be modified to do 64 bit operations directly.... + This code relies on being able to manipluate day numbers + and times using 32 bit arithmetic to crack a VMS quadword + byte by byte. If your C compiler doesn't have 32 bit unsigned + integer types then give up now! On a 64 bit systems VMSTIME_64BIT + can be defined to do 64 bit operations directly.... - One advantage of doing arihmetic byte by byte is that - the code does not depend on what 'endian' the target - machine is - it will always treat bytes in the same order! - (Hopefully VMS time bytes will always be in the same order!) + One advantage of doing arihmetic byte by byte is that + the code does not depend on what 'endian' the target + machine is - it will always treat bytes in the same order! + (Hopefully VMS time bytes will always be in the same order!) + + Note: VMS time quadwords are simply an eight byte integer + (quadword) representing the number of 100 nanasecond + units since 17-Nov-1858. Delta times (time differences) + are represented by a negative quadword value. It is + interesting that Windows UTC times are in the same units + but are based on the year 1601. A couple of stupid questions to go on with:- o OK, I give up! What is the difference between a zero @@ -32,23 +46,40 @@ o Anyone notice that the use of 16 bit words in sys$numtim restricts delta times to 65535 days? - Paul Nankervis + Paul Nankervis + paulnank@au1.ibm.com + + Note: The routine are defined here with an underscore instead + of a dollar symbol (ie sys_asctim instead of sys$asctim). + This avoids problems on systems which don't handle + the '$' well, and it avoids conflicts under VMS. + To call these routines from an application which uses + normal 'dollar' names simply include the header file + "vmstime.h" which will remap the names unless NO_DOLLAR + is defined first! (ie define sys$asctim as sys_asctim). */ #include -#include -#include "vmstime.h" /* Our header file! */ -#include /* C header for $GETTIM to find time */ +#include +#include +#include +#ifdef _WIN32 +#include /* Use windows routines to get currrent time */ +#else - -#ifndef SS$_NORMAL -#define SS$_NORMAL 1 -#define SS$_IVTIME 388 -#define LIB$_ONEDELTIM 1410020 +#ifndef NO_LOCALTIME +#if defined(VMS) && defined(__GNUC__) +#include /* For GCC include libraries on VMS (sigh!) */ +#else +#include /* For ftime() */ #endif +#endif +#endif + +#include "vmstime.h" /* Our header file! */ #define TIMEBASE 100000 /* 10 millisecond units in quadword */ @@ -63,468 +94,636 @@ #define YEAR_DAYS 365 /* 365 */ #define OFFSET_DAYS 94187 -/* ((1858_1601)*365) + ((1858_1601)/4) - ((1858_1601)/100) - + ((1858_1601)/400) + 320 +/* ((1858-1601)*365) + ((1858-1601)/4) - ((1858-1601)/100) + + ((1858-1601)/400) + 320 OFFSET FROM 1/1/1601 TO 17/11/1858 */ #define BASE_YEAR 1601 +/* lib$addx & lib$subx perform arithmetic using a small integer at + a time. Compare can be done using a full size integer (if the endian + is correct.Note that on a big endian machine the maximum unit of + work is always one character!!! +*/ -/* combine_date_time() is an internal routine to put date and time into a - quadword - basically the opposite of lib_day() .... */ +#ifdef VMSTIME_64BIT +#define LARGE_INT unsigned VMSTIME_64BIT +#define SMALL_INT unsigned int +#define WORK_INT unsigned VMSTIME_64BIT +#else -unsigned combine_date_time(int days,struct TIME *timadr,int day_time) +#define WORK_INT unsigned int +#if defined(VMS) || defined(_WIN32) +#define LARGE_INT unsigned int +#define SMALL_INT unsigned short +#else +#define SMALL_INT unsigned char +#endif + +#endif + +unsigned lib_addx(void *addant,void *addee,void *result,int *lenadd) { - if (day_time >= TIMESIZE) { - return SS$_IVTIME; + register int count; + if (lenadd == NULL) { + count = 8; } else { - - /* Put days into quad timbuf... */ - - register unsigned count,time; - register unsigned char *ptr; - count = 8; - ptr = timadr->time; - time = days; - do { - *ptr++ = time; - time = (time >> 8); - } while (--count > 0); - - /* Factor in the time... */ - - count = 8; - ptr = timadr->time; - time = day_time; - do { - time += *ptr * TIMESIZE; - *ptr++ = time; - time = (time >> 8); - } while (--count > 0); - - /* Factor by time base... */ - - count = 8; - ptr = timadr->time; - time = 0; - do { - time += *ptr * TIMEBASE; - *ptr++ = time; - time = (time >> 8); - } while (--count > 0); - - return SS$_NORMAL; + count = *lenadd * 4; } +#ifdef LARGE_INT + if (count == sizeof(LARGE_INT)) { + *(LARGE_INT *) result = *(LARGE_INT *) addant + *(LARGE_INT *) addee; + } else { +#else + { +#endif + register SMALL_INT *ant = (SMALL_INT *) addant; + register SMALL_INT *ee = (SMALL_INT *) addee; + register SMALL_INT *res = (SMALL_INT *) result; + register WORK_INT carry = 0; + count /= sizeof(SMALL_INT); + do { + carry = *ant++ + (carry + *ee++); + *res++ = carry; + carry = carry >> (sizeof(SMALL_INT) * 8); + } while (--count > 0); + } + return LIB__NORMAL; } - -/* sys_gettim() implemented here by getting UNIX time in seconds since - 1-Jan-1970 using time() and munging into a quadword... Some run time - systems don't seem to do this properly!!! Note that time() has a - resolution of only one second. */ - -unsigned sys_gettim(struct TIME *timadr) +unsigned lib_subx(void *subant,void *subee,void *result,int *lenadd) { - time_t curtim = time(NULL); - return combine_date_time(40587 + curtim / 86400,timadr, - (curtim % 86400) * 100); + register int count; + if (lenadd == NULL) { + count = 8; + } else { + count = *lenadd * 4; + } +#ifdef LARGE_INT + if (count == sizeof(LARGE_INT)) { + *(LARGE_INT *) result = *(LARGE_INT *) subant + *(LARGE_INT *) subee; + } else { +#else + { +#endif + register SMALL_INT *ant = (SMALL_INT *) subant; + register SMALL_INT *ee = (SMALL_INT *) subee; + register SMALL_INT *res = (SMALL_INT *) result; + register WORK_INT carry = 0; + count /= sizeof(SMALL_INT); + do { + carry = *ant++ - (carry + *ee++); + *res++ = carry; + carry = (carry >> (sizeof(SMALL_INT) * 8)) & 1; + } while (--count > 0); + } + return LIB__NORMAL; +} + +/* vmstime_compare() is used to compare times. + returns -1 if time2 is bigger + 0 if times are equal + 1 if time1 is bigger +*/ + +int vmstime_compare(VMSTIME time1,VMSTIME time2) +{ +#ifdef VMSTIME_64BIT + if (*time1 > *time2) return 1; + if (*time1 < *time2) return -1; +#else +#ifdef LARGE_INT + register int count = 8 / sizeof(LARGE_INT); + register LARGE_INT *t1 = (LARGE_INT *) time1 + 8 / sizeof(LARGE_INT) - 1; + register LARGE_INT *t2 = (LARGE_INT *) time2 + 8 / sizeof(LARGE_INT) - 1; +#else + register int count = 8 / sizeof(SMALL_INT); + register SMALL_INT *t1 = (SMALL_INT *) time1 + 8 / sizeof(SMALL_INT) - 1; + register SMALL_INT *t2 = (SMALL_INT *) time2 + 8 / sizeof(SMALL_INT) - 1; +#endif + do { + if (*t1 > *t2) return 1; + if (*t1 < *t2) return -1; + t1--; t2--; + } while (--count > 0); +#endif + return 0; } -/* lib_cvt_vectim() takes individual time fields in seven word buffer and - munges into a quadword... */ +/* vmstime_date_time() is an internal routine assemble the date (day number) + and time in a time quadword - basically the opposite of lib_day() +*/ -unsigned short month_end[] = {0,31,59,90,120,151,181,212,243,273,304,334,365}; - -unsigned lib_cvt_vectim(unsigned short timbuf[7],struct TIME *timadr) +unsigned vmstime_date_time(int days,VMSTIME timadr,int day_time) { - int delta = 0; - register unsigned sts,days,day_time; - sts = SS$_NORMAL; + /* Put date/time into VMS quadword timbuf... */ + +#ifdef VMSTIME_64BIT + if (day_time <= -TIMESIZE || day_time >= TIMESIZE) return SS__IVTIME; + *timadr = ((days * (VMSTIME_64BIT) TIMESIZE) + day_time) * TIMEBASE; +#else + register unsigned time = day_time; + register unsigned char *dstptr = timadr; + register int count = 8,carry = 0,date = days; + + if (day_time <= -TIMESIZE || day_time >= TIMESIZE) return SS__IVTIME; + + if (date == 0 && day_time < 0) { + do { + carry += (time & 0xFF) * TIMEBASE; + time = (time >> 8) | 0xFF000000; + *dstptr++ = carry; + carry = (carry >> 8); + } while (--count > 0); + } else{ + do { + time += (date & 0xFF) * TIMESIZE; + date = (date >> 8); + carry += (time & 0xFF) * TIMEBASE; + time = (time >> 8); + *dstptr++ = carry; + carry = (carry >> 8); + } while (--count > 0); + } +#endif + return SS__NORMAL; +} + + +/* lib_cvt_vectim() takes individual date/time fields from a + seven word buffer and munges them into a time quadword... +*/ + +int vmstime_mthend[] = {0,31,60,91,121,152,182,213,244,274,305,335,366}; + +unsigned lib_cvt_vectim(unsigned short timvec[7],VMSTIME timadr) +{ + register unsigned sts; + register int year,month,days; /* lib_cvt_vectim packs the seven date/time components into a quadword... */ - if (timbuf[0] == 0 && timbuf[1] == 0) { - delta = 1; - days = timbuf[2]; + if (timvec[3] > 23 || timvec[4] > 59 || + timvec[5] > 59 || timvec[6] > 99) return SS__IVTIME; + + year = timvec[0]; + month = timvec[1]; + days = timvec[2]; + + if (year == 0 && month == 0) { + + /* Pass back delta result */ + + sts = vmstime_date_time(-days,timadr,timvec[3] * -360000 - + timvec[4] * 6000 - timvec[5] * 100 - timvec[6]); } else { - register int leap = 0,year = timbuf[0],month = timbuf[1]; - if (month >= 2) { - if ((year % 4) == 0) { - if ((year % 100) == 0) { - if ((year % 400) == 0) { - leap = 1; - } - } else { - leap = 1; - } - } - } - days = timbuf[2]; - if (year >= 1858 && year <= 9999 && month >= 1 && - month <= 12 && days >= 1) { - days += month_end[month - 1]; - if (month > 2) days += leap; - if (days <= month_end[month] + leap) { - year -= BASE_YEAR; - days += year * 365 + year / 4 - year / 100 + year / 400 - - OFFSET_DAYS - 1; + + /* Generate days since base date.. */ + + int nonleap_adjust = 0; + if (year < 1858 || year > 9999 || + month < 1 || month > 12 || days < 1) return SS__IVTIME; + days += vmstime_mthend[month - 1]; + if (month > 1) { + if (year % 4) { + nonleap_adjust = 1; } else { - sts = SS$_IVTIME; + if ((year % 100) == 0 && year % 400) nonleap_adjust = 1; } - } else { - sts = SS$_IVTIME; - } - } - if (timbuf[3] > 23 || timbuf[4] > 59 || - timbuf[5] > 59 || timbuf[6] > 99) { - sts = SS$_IVTIME; - } - if (sts & 1) { - day_time = timbuf[3] * 360000 + timbuf[4] * 6000 + - timbuf[5] * 100 + timbuf[6]; - sts = combine_date_time(days,timadr,day_time); - if (delta) { - - /* We have to 2's complement delta times - sigh!! */ - - register unsigned count,time; - register unsigned char *ptr; - count = 8; - ptr = timadr->time; - time = 1; - do { - time = time + ((~*ptr) & 0xFF); - *ptr++ = time; - time = (time >> 8); - } while (--count > 0); } + if (days > vmstime_mthend[month] || (month == 2 && + days > vmstime_mthend[month] - nonleap_adjust)) return SS__IVTIME; + if (month > 2) days -= nonleap_adjust; + year -= BASE_YEAR; + days += year * YEAR_DAYS + year / 4 - year / 100 + year / 400 - + OFFSET_DAYS - 1; + sts = vmstime_date_time(days,timadr,timvec[3] * 360000 + + timvec[4] * 6000 + timvec[5] * 100 + timvec[6]); } return sts; } -/* lib_day() is a routine to crack quadword into day number and time */ -unsigned lib_day(int *days,struct TIME *timadr,int *day_time) +/* sys_gettim() implemented here by getting C library time in seconds + since 1-Jan-1970 and munging into a time quadword... Can use time() + to just get seconds or ftime() to find seconds with milli-seconds. + localtime() is used to find non-offset time. Note that some libraries + don't do any of this particularly well! Under windows we can use + a munged version of the internal UTC time +*/ + +unsigned sys_gettim(VMSTIME timadr) { - register unsigned date,time,count; - register unsigned char *dstptr,*srcptr; - struct TIME wrktim; - int delta; +#ifdef _WIN32 + /* Get windows time adjust for timezone and convert to VMS... */ + GetSystemTimeAsFileTime((struct _FILETIME *)timadr); + FileTimeToLocalFileTime((struct _FILETIME *)timadr,(struct _FILETIME *)timadr); + return vmstime_from_nt(timadr,timadr); +#else +#ifdef NO_LOCALTIME + /* Use time straight from time() */ + time_t curtim = time(NULL); + return vmstime_date_time(40587 + curtim / 86400,timadr, + (curtim % 86400) * 100); +#else + /* Get time from ftime() and localtime() */ + struct timeb timval; + struct tm *lclptr; + unsigned short timvec[7]; + timval.millitm = 0; /* for broken versions of ftime() */ + ftime(&timval); + lclptr = localtime(&timval.time); + timvec[0] = lclptr->tm_year + 1900; + timvec[1] = lclptr->tm_mon + 1; + timvec[2] = lclptr->tm_mday; + timvec[3] = lclptr->tm_hour; + timvec[4] = lclptr->tm_min; + timvec[5] = lclptr->tm_sec; + timvec[6] = timval.millitm / 10; + return lib_cvt_vectim(timvec,timadr); +#endif +#endif +} + + + +/* vmstime_day() is a routine to crack time quadwords into a day number + and time. It is different to lib_day() in that delta times are returned + as negative values to distinguish small delta values from dates +*/ + +unsigned vmstime_day(int *days,VMSTIME timadr,int *day_time) +{ + VMSTIME wrktim; +#ifdef VMSTIME_64BIT + register VMSTIME_64BIT timval; +#else + register int delta = 0; + register unsigned char *srcptr; +#endif /* If no time specified get current using gettim() */ if (timadr == NULL) { register unsigned sts; - sts = sys_gettim(&wrktim); - if ((sts & 1) == 0) { - return sts; - } - delta = 0; - srcptr = wrktim.time + 7; + sts = sys_gettim(wrktim); + if (!(sts & 1)) return sts; +#ifdef VMSTIME_64BIT + timval = *wrktim; + } else { + timval = *timadr; + } + timval /= TIMEBASE; + *days = (timval / TIMESIZE); + if (day_time != NULL) *day_time = (timval % TIMESIZE); + +#else + srcptr = wrktim + 7; } else { /* Check specified time for delta... */ - srcptr = timadr->time + 7; - if ((delta = (*srcptr & 0x80))) { + if ((delta = ISDELTA(timadr))) { /* We have to 2's complement delta times - sigh!! */ - count = 8; - srcptr = timadr->time; - dstptr = wrktim.time; - time = 1; + register int count = 8,carry = 1; + register unsigned char *dstptr = wrktim; + srcptr = timadr; do { - time = time + ((~*srcptr++) & 0xFF); - *dstptr++ = time; - time = (time >> 8); + carry += (~*srcptr++) & 0xFF; + *dstptr++ = carry; + carry = carry >> 8; } while (--count > 0); - srcptr = wrktim.time + 7; + srcptr = wrktim + 7; + + } else { + srcptr = timadr + 7; } } + /* Extract the date and time from the quadword... */ - /* Throw away the unrequired time precision */ + { + register int count = 5,date = 0; + register unsigned time = 0, carry; - count = 8; - dstptr = wrktim.time + 7; - time = 0; - do { - time = (time << 8) | *srcptr--; - *dstptr-- = time / TIMEBASE; - time %= TIMEBASE; - } while (--count > 0); + carry = *srcptr--; + carry = (carry << 8) | *srcptr--; + carry = (carry << 8) | *srcptr--; + do { + carry = (carry << 8) | *srcptr--; + time = (time << 8) | (carry / TIMEBASE); + date = (date << 8) | (time / TIMESIZE); + carry %= TIMEBASE; + time %= TIMESIZE; + } while (--count > 0); + /* Return results... */ - /* Seperate the date and time */ - - date = time = 0; - srcptr = wrktim.time + 7; - count = 8; - do { - time = (time << 8) | *srcptr--; - date = (date << 8) | (time / TIMESIZE); - time %= TIMESIZE; - } while (--count > 0); - - /* Return results... */ - - if (delta) { - *days = -(int) date; - if (day_time != NULL) *day_time = -(int) time; - } else { - *days = date; - if (day_time != NULL) *day_time = time; + if (delta) { + *days = -(int) date; + if (day_time != NULL) *day_time = -(int) time; + } else { + *days = date; + if (day_time != NULL) *day_time = time; + } } +#endif + return LIB__NORMAL; +} - return SS$_NORMAL; +/* lib_day() is a routine to crack time quadwords into a day number + and time. +*/ + +unsigned lib_day(int *days,VMSTIME timadr,int *day_time) +{ + register unsigned sts; + sts = vmstime_day(days,timadr,day_time); + if (*day_time < 0) *day_time = -*day_time; + return sts; } +/* vmstime_numtim() takes a time quadword and breaks it into a + seven word time vector (year,month,day,hour...) +*/ -/* sys_numtim() takes quadword and breaks it into a seven word time buffer */ - -unsigned char month_days[] = {31,29,31,30,31,30,31,31,30,31,30,31}; - -unsigned sys_numtim(unsigned short timbuf[7],struct TIME *timadr) +unsigned vmstime_numtim(unsigned short timvec[7],VMSTIME timadr, + int *days,int *day_time,int *day_of_year) { register int date,time; - /* Use lib_day to crack time into date/time... */ + /* Use vmstime_day to crack time into days/time... */ { - int days,day_time; register unsigned sts; - sts = lib_day(&days,timadr,&day_time); - if ((sts & 1) == 0) { - return sts; - } - date = days; - time = day_time; + sts = vmstime_day(days,timadr,day_time); + if (!(sts & 1)) return sts; + date = *days; + time = *day_time; } - /* Delta or date... */ + /* Delta time or date? */ if (date < 0 || time < 0) { - timbuf[2] = -date; /* Days */ - timbuf[1] = 0; /* Month */ - timbuf[0] = 0; /* Year */ + timvec[0] = 0; /* Year */ + timvec[1] = 0; /* Month */ + timvec[2] = -date; /* Days */ time = -time; } else { - /* Date... */ + /* Date - calculate years to quad century... */ - register int year,month; + register int year; date += OFFSET_DAYS; year = BASE_YEAR + (date / QUAD_CENTURY_DAYS) * 400; date %= QUAD_CENTURY_DAYS; - /* Kludge century division - last century in quad is longer!! */ + /* Add years to century - last century in quad is longer!! */ - if ((month = date / CENTURY_DAYS) == 4) month = 3; - date -= month * CENTURY_DAYS; - year += month * 100; + { + register int century = date / CENTURY_DAYS; + if (century == 4) century = 3; + if (century) { + year += century * 100; + date -= century * CENTURY_DAYS; + } + } - /* Use the same technique to find out the quad year and year - - last year in quad is longer!! */ + /* Add years to quad year... */ year += (date / QUAD_YEAR_DAYS) * 4; date %= QUAD_YEAR_DAYS; - if ((month = date / YEAR_DAYS) == 4) month = 3; - date -= month * YEAR_DAYS; - year += month; - - /* Adjust for years which have no Feb 29th */ - - if (date++ > 58) { - if (month != 3) { - date++; - } else { - if ((year % 100) == 0 && (year % 400) != 0) date++; - } - } - /* Figure out what month it is... */ + /* Finally to current year - last year in quad is longer!! */ { - unsigned char *mthptr = month_days; - month = 1; - while (date > *mthptr) { - date -= *mthptr++; - month++; + register int yearno = date / YEAR_DAYS; + if (yearno == 4) yearno = 3; + if (yearno) { + year += yearno; + date -= yearno * YEAR_DAYS; } } + if (day_of_year != NULL) *day_of_year = date; - /* Return date results... */ + /* Non-leap adjustment for years which have no Feb 29th */ - timbuf[2] = date; /* Days */ - timbuf[1] = month; /* Month */ - timbuf[0] = year; /* Year */ + if (date++ > 58) { + if (year % 4) { + date++; + } else { + if ((year % 100) == 0 && year % 400) date++; + } + } + /* Figure out month and return results... */ + + { + register int month = 1; + while (date > vmstime_mthend[month]) month++; + + timvec[0] = year; /* Year */ + timvec[1] = month; /* Month */ + timvec[2] = date - vmstime_mthend[month - 1]; /* Days */ + } } - /* Return time... */ + /* Return time information... */ - timbuf[6] = time % 100; /* Hundredths */ + timvec[6] = time % 100; /* Hundredths */ time /= 100; - timbuf[5] = time % 60; /* Seconds */ + timvec[5] = time % 60; /* Seconds */ time /= 60; - timbuf[4] = time % 60; /* Minutes */ - timbuf[3] = time / 60; /* Hours */ + timvec[4] = time % 60; /* Minutes */ + timvec[3] = time / 60; /* Hours */ - return SS$_NORMAL; + return SS__NORMAL; +} + +/* sys_numtim() takes a time quadword and breaks it into a + seven word time vector (year,month,day,hour...) +*/ + +unsigned sys_numtim(unsigned short timvec[7],VMSTIME timadr) +{ + int days,day_time; + return vmstime_numtim(timvec,timadr,&days,&day_time,NULL); +} + +/* Define internal tables... */ + +char vmstime_punct[] = "::."; +char vmstime_digits[] = "0123456789"; +char vmstime_months[] = "-JAN-FEB-MAR-APR-MAY-JUN-JUL-AUG-SEP-OCT-NOV-DEC-"; + +/* vmstime_getnum() internal routine to convert a printable number to binary */ + +char *vmstime_getnum(char *ptr,char *end,unsigned short *result,int *scale) +{ + register int numval = 0; + register int scaleval = 1; + register char *chrptr = ptr; + do { + register int binval = 0; + register char digit = *chrptr++; + do { + if (digit == vmstime_digits[binval]) break; + } while (++binval < 10); + numval = numval * 10 + binval; + scaleval *= 10; + } while (chrptr < end && isdigit(*chrptr)); + *result = numval; + *scale = scaleval; + return chrptr; } +#define NOVALUE 0xFFFF -/* sys_bintim() takes ascii time and convert it to a quadword */ +/* sys_bintim() takes a printable time and converts it to a time quadword */ -char month_names[] = "-JAN-FEB-MAR-APR-MAY-JUN-JUL-AUG-SEP-OCT-NOV-DEC-"; -char time_sep[] = "::."; - -unsigned sys_bintim(struct dsc$descriptor *timbuf,struct TIME *timadr) +unsigned sys_bintim(struct dsc_descriptor *timbuf,VMSTIME timadr) { - register int length = timbuf->dsc$w_length; - register char *chrptr = timbuf->dsc$a_pointer; + int scale; unsigned short wrktim[7]; - int num,tf; + register int field_count = 0; + register char *chrptr = timbuf->dsc_a_pointer; + register char *endptr = chrptr + timbuf->dsc_w_length; + /* Skip any spaces... */ - /* Skip leading spaces... */ + while (chrptr < endptr && *chrptr == ' ') chrptr++; - while (length > 0 && *chrptr == ' ') { - length--; - chrptr++; + /* Get the day number or delta days... */ + + if (chrptr < endptr && isdigit(*chrptr)) { + chrptr = vmstime_getnum(chrptr,endptr,&wrktim[2],&scale); + field_count++; + } else { + wrktim[2] = NOVALUE; } - /* Get the day number... */ + /* Check for month separator "-" - if found then we have a date! */ - num = -1; - if (length > 0 && *chrptr >= '0' && *chrptr <= '9') { - num = 0; - do { - num = num * 10 + (*chrptr++ - '0'); - } while (--length > 0 && *chrptr >= '0' && *chrptr <= '9'); - } - /* Check for month separator "-" - if none delta time... */ - - if (length > 0 && *chrptr == '-') { + if (chrptr < endptr && *chrptr == '-') { chrptr++; - /* Get current time for defaults... */ + wrktim[0] = wrktim[1] = NOVALUE; + wrktim[3] = wrktim[4] = wrktim[5] = wrktim[6] = NOVALUE; - sys_numtim(wrktim,NULL); - if (num >= 0) wrktim[2] = num; - num = 0; - if (--length >= 3 && *chrptr != '-') { - char *mn = month_names + 1; - num = 1; - while (num <= 12) { - if (memcmp(chrptr,mn,3) == 0) break; - mn += 4; - num++; - } + /* See if there is a month... */ + + if (chrptr + 2 < endptr && *chrptr != '-') { + register int month = 1; + register char upmth0 = toupper(chrptr[0]); + register char upmth1 = toupper(chrptr[1]); + register char upmth2 = toupper(chrptr[2]); + register char *mthptr = vmstime_months + 1; + do { + if (upmth0 == mthptr[0] && + upmth1 == mthptr[1] && + upmth2 == mthptr[2]) break; + mthptr += 4; + } while (++month <= 12); chrptr += 3; - length -= 3; - wrktim[1] = num; + wrktim[1] = month; + field_count++; } /* Now look for year... */ - if (length > 0 && *chrptr == '-') { - length--; + if (chrptr < endptr && *chrptr == '-') { chrptr++; - if (length > 0 && *chrptr >= '0' && *chrptr <= '9') { - num = 0; - do { - num = num * 10 + (*chrptr++ - '0'); - } while (--length > 0 && *chrptr >= '0' && *chrptr <= '9'); - wrktim[0] = num; + if (chrptr < endptr && isdigit(*chrptr)) { + chrptr = vmstime_getnum(chrptr,endptr,&wrktim[0],&scale); + field_count++; } } } else { - /* Delta time then... */ + /* Set default values for delta time... */ wrktim[0] = wrktim[1] = 0; - wrktim[2] = num; wrktim[3] = wrktim[4] = wrktim[5] = wrktim[6] = 0; - } + if (wrktim[2] == NOVALUE) wrktim[2] = 0; - /* Skip any spaces between date and time... */ + /* If no space then just a time value? */ - while (length > 0 && *chrptr == ' ') { - length--; - chrptr++; - } - - /* Now wrap up time fields... */ - - for (tf = 0; tf < 3; tf++) { - if (length > 0 && *chrptr >= '0' && *chrptr <= '9') { - num = 0; - do { - num = num * 10 + (*chrptr++ - '0'); - } while (--length > 0 && *chrptr >= '0' && *chrptr <= '9'); - wrktim[3 + tf] = num; - if (num > 59) wrktim[1] = 13; + if (chrptr < endptr && *chrptr != ' ') { + wrktim[3] = wrktim[2]; + wrktim[2] = 0; } - if (length > 0 && *chrptr == time_sep[tf]) { - length--; - chrptr++; - } else { - break; + field_count = 7; /* Don't use current time! */ + } + + /* Skip any spaces... */ + + while (chrptr < endptr && *chrptr == ' ') chrptr++; + + /* Extract time fields... Note: we don't round hundredths into seconds */ + + { + register int time_field; + for (time_field = 0; time_field < 4 && chrptr < endptr; time_field++) { + if (chrptr < endptr && isdigit(*chrptr)) { + chrptr = vmstime_getnum(chrptr,endptr,&wrktim[time_field + 3],&scale); + field_count++; + if (time_field == 3) { + register unsigned hundredth = wrktim[6] * 1000 / scale; + if (hundredth < 995) hundredth += 5; + wrktim[6] = hundredth / 10; + break; + } + } + if (chrptr < endptr && time_field < 3 && + *chrptr == vmstime_punct[time_field]) chrptr++; } } - /* Hundredths of seconds need special handling... */ + /* Skip any spaces... */ - if (length > 0 && *chrptr >= '0' && *chrptr <= '9') { - tf = 10; - num = 0; - do { - num = num + tf * (*chrptr++ - '0'); - tf = tf / 10; - } while (--length > 0 && *chrptr >= '0' && *chrptr <= '9'); - wrktim[6] = num; - } - /* Now skip any trailing spaces... */ - - while (length > 0 && *chrptr == ' ') { - length--; - chrptr++; - } + while (chrptr < endptr && *chrptr == ' ') chrptr++; /* If anything left then we have a problem... */ - if (length == 0) { - return lib_cvt_vectim(wrktim,timadr); - } else { - return SS$_IVTIME; + if (chrptr < endptr) return SS__IVTIME; + + /* If some fields not specified use current time...*/ + + if (field_count < 7) { + register int field; + unsigned short curtim[7]; + register unsigned sts = sys_numtim(curtim,NULL); + if (!(sts & 1)) return sts; + for (field = 0; field < 7; field++) { + if (wrktim[field] == NOVALUE) wrktim[field] = curtim[field]; + } } + return lib_cvt_vectim(wrktim,timadr); } -/* sys_asctim() converts quadword to ascii... */ +/* sys_asctim() converts a time quadword into printable form... */ -unsigned sys_asctim(unsigned short *timlen,struct dsc$descriptor *timbuf, - struct TIME *timadr,unsigned cvtflg) +unsigned sys_asctim(unsigned short *timlen,struct dsc_descriptor *timbuf, + VMSTIME timadr,unsigned cvtflg) { + unsigned short timvec[7]; register int count,timval; - unsigned short wrktim[7]; - register int length = timbuf->dsc$w_length; - register char *chrptr = timbuf->dsc$a_pointer; + register char *chrptr = timbuf->dsc_a_pointer; + register char *endptr = chrptr + timbuf->dsc_w_length; /* First use sys_numtim to get the date/time fields... */ { register unsigned sts; - sts = sys_numtim(wrktim,timadr); - if ((sts & 1) == 0) { - return sts; - } + sts = sys_numtim(timvec,timadr); + if (!(sts & 1)) return sts; } /* See if we want delta days or date... */ @@ -533,91 +732,88 @@ unsigned sys_asctim(unsigned short *timlen,struct dsc$descriptor *timbuf, /* Check if date or delta time... */ - if (*wrktim) { + if (timvec[0]) { - /* Put in days and month... */ + /* Generate two digit day... */ - if (length > 0) { - if ((timval = wrktim[2]) / 10 == 0) { + if (chrptr < endptr) { + if ((timval = timvec[2]) / 10 == 0) { *chrptr++ = ' '; } else { - *chrptr++ = '0' + timval / 10; + *chrptr++ = vmstime_digits[timval / 10]; } - length--; } - if (length > 0) { - *chrptr++ = '0' + (timval % 10); - length--; + if (chrptr < endptr) { + *chrptr++ = vmstime_digits[timval % 10]; } - if ((count = length) > 5) count = 5; - memcpy(chrptr,month_names + (wrktim[1] * 4 - 4),count); - length -= count; + /* Add month name with hyphen separators... */ + + if ((count = (endptr - chrptr)) > 5) count = 5; + memcpy(chrptr,vmstime_months + ((timvec[1] - 1) * 4),count); chrptr += count; - timval = *wrktim; + + /* Get year... */ + + timval = timvec[0]; + } else { /* Get delta days... */ - timval = wrktim[2]; + timval = timvec[2]; } - /* Common code for year number and delta days!! */ + /* Common code for year number and delta days! Spaces first... */ - count = 10000; - if (timval < count) { - count = 1000; - while (length > 0 && timval < count && count > 1) { - length--; + count = 1000; + if (timval < count && chrptr < endptr) { + do { *chrptr++ = ' '; count /= 10; - } - } - while (length > 0 && count > 0) { - length--; - *chrptr++ = '0' + (timval / count); - timval = timval % count; - count /= 10; - } - - /* Space between date and time... */ - - if (length > 0) { - *chrptr++ = ' '; - length--; - } - } - /* Do time... :-) */ - - count = 3; - do { - timval = wrktim[count]; - if (length >= 1) *chrptr++ = '0' + (timval / 10); - if (length >= 2) { - *chrptr++ = '0' + (timval % 10); - length -= 2; + } while (timval < count && count > 1 && chrptr < endptr); } else { - length = 0; + if (timval >= 10000) count = 10000; } - if (count < 6 && length > 0) { - length--; - if (count == 5) { - *chrptr++ = '.'; - } else { - *chrptr++ = ':'; - } + /* Then digits... */ + + if (chrptr < endptr) { + do { + *chrptr++ = vmstime_digits[timval / count]; + timval = timval % count; + count /= 10; + } while (count > 0 && chrptr < endptr); } - } while (++count < 7); - /* We've done it - time to return length... */ + /* Put a space between date and time... */ - if (timlen != NULL) *timlen = timbuf->dsc$w_length - length; - return SS$_NORMAL; + if (chrptr < endptr) *chrptr++ = ' '; + + } + /* Move onto time fields... hh:mm:ss.hh */ + + if (chrptr < endptr) { + count = 0; + do { + timval = timvec[count + 3]; + *chrptr++ = vmstime_digits[timval / 10]; + if (chrptr >= endptr) break; + *chrptr++ = vmstime_digits[timval % 10]; + if (count >= 3 || chrptr >= endptr) break; + *chrptr++ = vmstime_punct[count++]; + } while (chrptr < endptr); + } + + /* We've done it - return length... */ + + if (timlen != NULL) *timlen = (chrptr - (char *) timbuf->dsc_a_pointer); + + return SS__NORMAL; } -/* lib_day_of_week() computes day of week from quadword... */ +/* lib_day_of_week() computes day of week from time quadword... */ -unsigned lib_day_of_week(struct TIME *timadr,unsigned *weekday) +unsigned lib_day_of_week(VMSTIME timadr,unsigned *weekday) { int days; register unsigned sts; @@ -631,124 +827,261 @@ unsigned lib_day_of_week(struct TIME *timadr,unsigned *weekday) return sts; } +/* lib_mult_delta_time multiplies a delta time by a scalar integer... */ -/* addx & subx COULD use 32 bit arithmetic to do a word at a time. But - this only works on hardware which has the same endian as the VAX! - (Intel works fine!! :-) ) So this version works byte by byte which - should work on VMS dates regardless of system endian - but they - will NOT perform arithmetic correctly for other data types on - systems with opposite endian!!! */ - -unsigned lib_addx(void *addant,void *addee,void *result,int *lenadd) +unsigned lib_mult_delta_time(int *multiple,VMSTIME timadr) { - register int count; - register unsigned carry = 0; - register unsigned char *ant = (unsigned char *) addant; - register unsigned char *ee = (unsigned char *) addee; - register unsigned char *res = (unsigned char *) result; - if (lenadd == NULL) { - count = 8; - } else { - count = *lenadd * 4; - } - - while (count-- > 0) { - carry = *ant++ + (carry + *ee++); - *res++ = carry; - carry = carry >> 8; - } - return SS$_NORMAL; -} - - -unsigned lib_subx(void *subant,void *subee,void *result,int *lenadd) -{ - register int count; - register unsigned carry = 0; - register unsigned char *ant = (unsigned char *) subant; - register unsigned char *ee = (unsigned char *) subee; - register unsigned char *res = (unsigned char *) result; - if (lenadd == NULL) { - count = 8; - } else { - count = *lenadd * 4; - } - - while (count-- > 0) { - carry = *ant++ - (carry + *ee++); - *res++ = carry; - carry = (carry >> 8) & 1; - - } - return SS$_NORMAL; -} - - - -unsigned lib_add_times(struct TIME *time1,struct TIME *time2, - struct TIME *result) -{ - if (time1->time[7] & 0x80) { - if (time2->time[7] & 0x80) { - return lib_addx(time1,time2,result,NULL); - } else { - return lib_subx(time2,time1,result,NULL); - } - } else { - if (time2->time[7] & 0x80) { - return lib_subx(time1,time2,result,NULL); - } else { - return LIB$_ONEDELTIM; - } - } -} - - - -unsigned lib_sub_times(struct TIME *time1,struct TIME *time2, - struct TIME *result) -{ - if ((time1->time[7] & 0x80) != (time2->time[7] & 0x80)) { - return lib_addx(time1,time2,result,NULL); - } else { - register int cmp,count = 7; - do { - if ((cmp = (time1->time[count] - time2->time[count]))) break; - } while (--count >= 0); - if (cmp < 0) { - return lib_subx(time1,time2,result,NULL); - } else { - return lib_subx(time2,time1,result,NULL); - } - } -} - - - -unsigned lib_mult_delta_time(int *multiple,struct TIME *timadr) -{ - register unsigned count = 8,carry = 0; register int factor = *multiple; - register unsigned char *ptr = timadr->time; /* Check for delta time... */ - if (timadr->time[7] & 0x80) { + if (!ISDELTA(timadr)) return SS__IVTIME; - /* Use absolute factor... */ + /* Use absolute factor... */ - if (factor < 0) factor = -factor; - - /* Multiply delta time... */ + if (factor < 0) factor = -factor; +#ifdef VMSTIME_64BIT + *timadr *= factor; +#else + { + register int count = 8; + register unsigned carry = 0; + register unsigned char *ptr = timadr; do { carry += *ptr * factor; *ptr++ = carry; carry = (carry >> 8); } while (--count > 0); - - return SS$_NORMAL; - } else { - return SS$_IVTIME; } +#endif + return LIB__NORMAL; +} + + +/* lib_add_times() adds two quadword time values */ + +unsigned lib_add_times(VMSTIME time1,VMSTIME time2,VMSTIME result) +{ + if (ISDELTA(time1)) { + if (ISDELTA(time2)) { +#ifdef VMSTIME_64BIT + *result = *time1 + *time2; + } else { + *result = *time2 - *time1; +#else + lib_addx(time1,time2,result,NULL); + } else { + lib_subx(time2,time1,result,NULL); +#endif + } + } else { + if (ISDELTA(time2)) { +#ifdef VMSTIME_64BIT + *result = *time1 - *time2; +#else + lib_subx(time1,time2,result,NULL); +#endif + } else { + return LIB__ONEDELTIM; + } + } + return LIB__NORMAL; +} + + +/* lib_sub_times() subtracts two quadword time values */ + +unsigned lib_sub_times(VMSTIME time1,VMSTIME time2,VMSTIME result) +{ +#ifdef VMSTIME_64BIT + if (ISDELTA(time1) != ISDELTA(time2)) { + *result = *time1 + *time2; + } else { + if (*time1 < *time2) { + *result = *time1 - *time2; + } else { + *result = *time2 - *time1; + } + } +#else + if (ISDELTA(time1) != ISDELTA(time2)) { + lib_addx(time1,time2,result,NULL); + } else { + if (vmstime_compare(time1,time2) < 0) { + lib_subx(time1,time2,result,NULL); + } else { + lib_subx(time2,time1,result,NULL); + } + } +#endif + return LIB__NORMAL; +} + + +/* lib_cvt_from_internal_time() extracts a time field from a time value */ + +unsigned lib_cvt_from_internal_time(unsigned *operation, + unsigned *result,VMSTIME input_time) +{ + register unsigned resval; + unsigned short timvec[7]; + int days,day_time,day_of_year; + if (*operation >= LIB$K_MAX_OPERATION) return LIB__INVOPER; + { + register unsigned sts; + sts = vmstime_numtim(timvec,input_time,&days,&day_time,&day_of_year); + if (!(sts & 1)) return sts; + } + if (timvec[0] != 0) { + switch (*operation) { + case LIB$K_MONTH_OF_YEAR: + resval = timvec[1]; + break; + case LIB$K_DAY_OF_YEAR: + resval = day_of_year + 1; + break; + case LIB$K_HOUR_OF_YEAR: + resval = day_of_year * 24 + timvec[3]; + break; + case LIB$K_MINUTE_OF_YEAR: + resval = (day_of_year * 24 + timvec[3]) * 60 + timvec[4]; + break; + case LIB$K_SECOND_OF_YEAR: + resval = ((day_of_year * 24 + timvec[3]) * 60 + timvec[4]) * 60 + timvec[5]; + break; + case LIB$K_DAY_OF_MONTH: + resval = timvec[2]; + break; + case LIB$K_HOUR_OF_MONTH: + resval = (timvec[2] - 1) * 24 + timvec[3]; + break; + case LIB$K_MINUTE_OF_MONTH: + resval = ((timvec[2] - 1) * 24 + timvec[3]) * 60 + timvec[4]; + break; + case LIB$K_SECOND_OF_MONTH: + resval = (((timvec[2] - 1) * 24 + timvec[3]) * 60 + timvec[4]) * 60 + timvec[5]; + break; + case LIB$K_DAY_OF_WEEK: + resval = ((days + 2) % 7) + 1; + break; + case LIB$K_HOUR_OF_WEEK: + resval = ((days + 2) % 7) * 24 + timvec[3]; + break; + case LIB$K_MINUTE_OF_WEEK: + resval = (((days + 2) % 7) * 24 + timvec[3]) * 60 + timvec[4]; + break; + case LIB$K_SECOND_OF_WEEK: + resval = ((((days + 2) % 7) * 24 + timvec[3]) * 60 + timvec[4]) * 60 + timvec[5]; + break; + case LIB$K_HOUR_OF_DAY: + resval = timvec[3]; + break; + case LIB$K_MINUTE_OF_DAY: + resval = timvec[3] * 60 + timvec[4]; + break; + case LIB$K_SECOND_OF_DAY: + resval = (timvec[3] * 60 + timvec[4]) * 60 + timvec[5]; + break; + case LIB$K_MINUTE_OF_HOUR: + resval = timvec[4]; + break; + case LIB$K_SECOND_OF_HOUR: + resval = timvec[4] * 60 + timvec[5]; + break; + case LIB$K_SECOND_OF_MINUTE: + resval = timvec[5]; + break; + case LIB$K_JULIAN_DATE: + resval = days; + break; + default: + return LIB__DELTIMREQ; + } + } else { + switch (*operation) { + case LIB$K_DELTA_WEEKS: + resval = timvec[2] / 7; + break; + case LIB$K_DELTA_DAYS: + resval = timvec[2]; + break; + case LIB$K_DELTA_HOURS: + resval = timvec[2] * 24 + timvec[3]; + break; + case LIB$K_DELTA_MINUTES: + resval = (timvec[2] * 24 + timvec[3]) * 60 + timvec[4]; + break; + case LIB$K_DELTA_SECONDS: + resval = ((timvec[2] * 24 + timvec[3]) * 60 + timvec[4]) * 60 + timvec[5]; + break; + case 0: + case LIB$K_DELTA_WEEKS_F: + case LIB$K_DELTA_DAYS_F: + case LIB$K_DELTA_HOURS_F: + case LIB$K_DELTA_MINUTES_F: + case LIB$K_DELTA_SECONDS_F: + return LIB__INVOPER; + default: + return LIB__ABSTIMREQ; + } + } + *result = resval; + return LIB__NORMAL; +} + +unsigned char vmstime_oneweek[] = {0x00,0xc0,0x1b,0xd7,0x7f,0xfa,0xff,0xff}; +unsigned char vmstime_oneday[] = {0x00,0x40,0x96,0xd5,0x36,0xff,0xff,0xff}; +unsigned char vmstime_onehour[] = {0x00,0x98,0x3b,0x9e,0xf7,0xff,0xff,0xff}; +unsigned char vmstime_oneminute[] = {0x00,0xba,0x3c,0xdc,0xff,0xff,0xff,0xff}; +unsigned char vmstime_onesecond[] = {0x80,0x69,0x67,0xff,0xff,0xff,0xff,0xff}; + +/* lib_cvt_to_internal_time() converts a time field to a time value */ + +unsigned lib_cvt_to_internal_time(unsigned *operation,int *input, + VMSTIME result) +{ + unsigned char *ptr; + if (*input < 1) return LIB__IVTIME; + switch (*operation) { + case LIB$K_DELTA_WEEKS: + ptr = vmstime_oneweek; + break; + case LIB$K_DELTA_DAYS: + ptr = vmstime_oneday; + break; + case LIB$K_DELTA_HOURS: + ptr = vmstime_onehour; + break; + case LIB$K_DELTA_MINUTES: + ptr = vmstime_oneminute; + break; + case LIB$K_DELTA_SECONDS: + ptr = vmstime_onesecond; + break; + default: + return LIB__INVOPER; + } + memcpy(result,ptr,sizeof(VMSTIME)); + return lib_mult_delta_time(input,result); +} + +/* Difference between VMS and NT is 94187 days.... */ + +unsigned char vmstime_nt_offset[] = {0x00,0xc0,0xac,0x76,0x88,0xe3,0xde,0xfe}; + +/* vmstime_from_nt() convert Windows NT time to vmstime */ + +unsigned vmstime_from_nt(VMSTIME nt_time,VMSTIME vms_time) +{ + if (ISDELTA(nt_time)) return LIB__IVTIME; + return lib_sub_times(nt_time,(pVMSTIME) vmstime_nt_offset,vms_time); +} + +/* vmstime_to_nt() convert vmstime to Windows NT time */ + +unsigned vmstime_to_nt(VMSTIME vms_time,VMSTIME nt_time) +{ + if (ISDELTA(vms_time)) return LIB__IVTIME; + return lib_add_times(vms_time,(pVMSTIME) vmstime_nt_offset,nt_time); } diff --git a/extracters/ods2/vmstime.h b/extracters/ods2/vmstime.h index a0ba082..fb1a333 100644 --- a/extracters/ods2/vmstime.h +++ b/extracters/ods2/vmstime.h @@ -1,10 +1,16 @@ /* - VMSTIME.H v1.1 + Vmstime.h v1.6A Author: Paul Nankervis - Please send bug reports to PaulNank@au1.ibm.com + Please send bug reports to Paulnank@au1.ibm.com + + 1.4A Changed default DOLLAR handling to include DOLLAR + identifers unless NO_DOLLAR is defined + (ie #ifdef DOLLAR to #ifndef NO_DOLLAR) + 1.5 Moved more header info here and added cvt_internal support + 1.6A Fixed endian problems in addx/subx */ @@ -14,39 +20,155 @@ #include "descrip.h" +#ifdef __ALPHA +#define VMSTIME_64BIT __int64 +#endif -struct TIME { - unsigned char time[8]; /* Structure of time */ -}; /* Look out Einstein!! :-) */ +/* Define quadword time type and test for delta times... */ +#ifdef VMSTIME_64BIT +typedef VMSTIME_64BIT VMSTIME[1]; +typedef VMSTIME_64BIT *pVMSTIME; +#define ISDELTA(x) (*x < 0) +#define VMSTIME_ZERO {0} +#else +typedef unsigned char VMSTIME[8]; +typedef unsigned char *pVMSTIME; +#define ISDELTA(x) (x[7] & 0x80) +#define VMSTIME_ZERO {0,0,0,0,0,0,0,0} +#endif + +/* Define status codes we require... note that if the real code values + are being included (SSDEF.H) then they should be included first!!! */ + +#ifndef SS__NORMAL +#define SS__NORMAL 1 +#define SS__IVTIME 388 +#define LIB__NORMAL 1409025 +#define LIB__IVTIME 1410012 +#define LIB__ONEDELTIM 1410020 +#define LIB__ABSTIMREQ 1410044 +#define LIB__DELTIMREQ 1410052 +#define LIB__INVOPER 1410060 + +#ifndef NO_DOLLAR +#ifndef SS$_NORMAL +#define SS$_NORMAL SS__NORMAL +#define SS$_IVTIME SS__IVTIME +#define LIB$_NORMAL LIB__NORMAL +#define LIB$_IVTIME LIB__IVTIME +#define LIB$_ONEDELTIM LIB__ONEDELTIM +#define LIB$_ABSTIMREQ LIB__ABSTIMREQ +#define LIB$_DELTIMREQ LIB__DELTIMREQ +#define LIB$_INVOPER LIB__INVOPER +#endif +#endif +#endif + +/* Constants for lib$cvt_ routines */ + +#define LIB_K_MONTH_OF_YEAR 1 +#define LIB_K_DAY_OF_YEAR 2 +#define LIB_K_HOUR_OF_YEAR 3 +#define LIB_K_MINUTE_OF_YEAR 4 +#define LIB_K_SECOND_OF_YEAR 5 +#define LIB_K_DAY_OF_MONTH 6 +#define LIB_K_HOUR_OF_MONTH 7 +#define LIB_K_MINUTE_OF_MONTH 8 +#define LIB_K_SECOND_OF_MONTH 9 +#define LIB_K_DAY_OF_WEEK 10 +#define LIB_K_HOUR_OF_WEEK 11 +#define LIB_K_MINUTE_OF_WEEK 12 +#define LIB_K_SECOND_OF_WEEK 13 +#define LIB_K_HOUR_OF_DAY 14 +#define LIB_K_MINUTE_OF_DAY 15 +#define LIB_K_SECOND_OF_DAY 16 +#define LIB_K_MINUTE_OF_HOUR 17 +#define LIB_K_SECOND_OF_HOUR 18 +#define LIB_K_SECOND_OF_MINUTE 19 +#define LIB_K_JULIAN_DATE 20 +#define LIB_K_DELTA_WEEKS 21 +#define LIB_K_DELTA_DAYS 22 +#define LIB_K_DELTA_HOURS 23 +#define LIB_K_DELTA_MINUTES 24 +#define LIB_K_DELTA_SECONDS 25 +#define LIB_K_DELTA_WEEKS_F 26 +#define LIB_K_DELTA_DAYS_F 27 +#define LIB_K_DELTA_HOURS_F 28 +#define LIB_K_DELTA_MINUTES_F 29 +#define LIB_K_DELTA_SECONDS_F 30 +#define LIB_K_MAX_OPERATION 31 + +/* For system which can use a dollar symbol...*/ + +#ifndef NO_DOLLAR +#define sys$asctim sys_asctim +#define sys$bintim sys_bintim +#define sys$gettim sys_gettim +#define sys$numtim sys_numtim #define lib$add_times lib_add_times #define lib$addx lib_addx +#define lib$cvt_from_internal_time lib_cvt_from_internal_time +#define lib$cvt_to_internal_time lib_cvt_to_internal_time #define lib$cvt_vectim lib_cvt_vectim #define lib$day lib_day #define lib$day_of_week lib_day_of_week #define lib$mult_delta_time lib_mult_delta_time #define lib$sub_times lib_sub_times #define lib$subx lib_subx -#define sys$asctim sys_asctim -#define sys$bintim sys_bintim -#define sys$gettim sys_gettim -#define sys$numtim sys_numtim - - -unsigned sys_gettim(struct TIME *timadr); -unsigned lib_cvt_vectim(unsigned short timbuf[7],struct TIME *timadr); -unsigned lib_day(int *days,struct TIME *timadr,int *day_time); -unsigned sys_numtim(unsigned short timbuf[7],struct TIME *timadr); -unsigned sys_bintim(struct dsc$descriptor *timbuf,struct TIME *timadr); -unsigned sys_asctim(unsigned short *timlen,struct dsc$descriptor *timbuf, - struct TIME *timadr,unsigned cvtflg); -unsigned lib_day_of_week(struct TIME *timadr,unsigned *weekday); -unsigned lib_addx(void *addant,void *addee,void *result,int *lenadd); -unsigned lib_subx(void *subant,void *subee,void *result,int *lenadd); -unsigned lib_add_times(struct TIME *time1,struct TIME *time2, - struct TIME *result); -unsigned lib_sub_times(struct TIME *time1,struct TIME *time2, - struct TIME *result); -unsigned lib_mult_delta_time(int *multiple,struct TIME *timadr); +#define LIB$K_MONTH_OF_YEAR LIB_K_MONTH_OF_YEAR +#define LIB$K_DAY_OF_YEAR LIB_K_DAY_OF_YEAR +#define LIB$K_HOUR_OF_YEAR LIB_K_HOUR_OF_YEAR +#define LIB$K_MINUTE_OF_YEAR LIB_K_MINUTE_OF_YEAR +#define LIB$K_SECOND_OF_YEAR LIB_K_SECOND_OF_YEAR +#define LIB$K_DAY_OF_MONTH LIB_K_DAY_OF_MONTH +#define LIB$K_HOUR_OF_MONTH LIB_K_HOUR_OF_MONTH +#define LIB$K_MINUTE_OF_MONTH LIB_K_MINUTE_OF_MONTH +#define LIB$K_SECOND_OF_MONTH LIB_K_SECOND_OF_MONTH +#define LIB$K_DAY_OF_WEEK LIB_K_DAY_OF_WEEK +#define LIB$K_HOUR_OF_WEEK LIB_K_HOUR_OF_WEEK +#define LIB$K_MINUTE_OF_WEEK LIB_K_MINUTE_OF_WEEK +#define LIB$K_SECOND_OF_WEEK LIB_K_SECOND_OF_WEEK +#define LIB$K_HOUR_OF_DAY LIB_K_HOUR_OF_DAY +#define LIB$K_MINUTE_OF_DAY LIB_K_MINUTE_OF_DAY +#define LIB$K_SECOND_OF_DAY LIB_K_SECOND_OF_DAY +#define LIB$K_MINUTE_OF_HOUR LIB_K_MINUTE_OF_HOUR +#define LIB$K_SECOND_OF_HOUR LIB_K_SECOND_OF_HOUR +#define LIB$K_SECOND_OF_MINUTE LIB_K_SECOND_OF_MINUTE +#define LIB$K_JULIAN_DATE LIB_K_JULIAN_DATE +#define LIB$K_DELTA_WEEKS LIB_K_DELTA_WEEKS +#define LIB$K_DELTA_DAYS LIB_K_DELTA_DAYS +#define LIB$K_DELTA_HOURS LIB_K_DELTA_HOURS +#define LIB$K_DELTA_MINUTES LIB_K_DELTA_MINUTES +#define LIB$K_DELTA_SECONDS LIB_K_DELTA_SECONDS +#define LIB$K_DELTA_WEEKS_F LIB_K_DELTA_WEEKS_F +#define LIB$K_DELTA_DAYS_F LIB_K_DELTA_DAYS_F +#define LIB$K_DELTA_HOURS_F LIB_K_DELTA_HOURS_F +#define LIB$K_DELTA_MINUTES_F LIB_K_DELTA_MINUTES_F +#define LIB$K_DELTA_SECONDS_F LIB_K_DELTA_SECONDS_F +#define LIB$K_MAX_OPERATION LIB_K_MAX_OPERATION +#endif + + +unsigned sys_gettim(VMSTIME timadr); +unsigned sys_numtim(unsigned short timvec[7],VMSTIME timadr); +unsigned sys_bintim(struct dsc_descriptor *timbuf,VMSTIME timadr); +unsigned sys_asctim(unsigned short *timlen,struct dsc_descriptor *timbuf, + VMSTIME timadr,unsigned cvtflg); +unsigned lib_add_times(VMSTIME time1,VMSTIME time2,VMSTIME result); +unsigned lib_addx(void *addant,void *addee,void *result,int *lenadd); +unsigned lib_cvt_from_internal_time(unsigned *operation, + unsigned *result,VMSTIME input_time); +unsigned lib_cvt_to_internal_time(unsigned *operation,int *input, + VMSTIME result); +unsigned lib_cvt_vectim(unsigned short timbuf[7],VMSTIME timadr); +unsigned lib_day(int *days,VMSTIME timadr,int *day_time); +unsigned lib_day_of_week(VMSTIME timadr,unsigned *weekday); +unsigned lib_mult_delta_time(int *multiple,VMSTIME timadr); +unsigned lib_subx(void *subant,void *subee,void *result,int *lenadd); +unsigned lib_sub_times(VMSTIME time1,VMSTIME time2,VMSTIME result); +unsigned vmstime_from_nt(VMSTIME nt_time,VMSTIME vms_time); +unsigned vmstime_to_nt(VMSTIME vms_time,VMSTIME nt_time); +int vmstime_compare(VMSTIME time1,VMSTIME time2); #endif diff --git a/extracters/ods2/wnaspi32.def b/extracters/ods2/wnaspi32.def new file mode 100644 index 0000000..a59b3a6 --- /dev/null +++ b/extracters/ods2/wnaspi32.def @@ -0,0 +1,6 @@ +LIBRARY WNASPI32 +EXPORTS + GetASPI32SupportInfo @1 + SendASPI32Command @2 +; Make library with +; LIB /DEF:WNASPI32.DEF /MACHINE:IX86 diff --git a/extracters/ods2/wnaspi32.exp b/extracters/ods2/wnaspi32.exp new file mode 100644 index 0000000000000000000000000000000000000000..42a77da97ff1b2df3548b2b29e2495ad262cae99 GIT binary patch literal 781 zcmZ`$%}&BV5FUQCYB&(R7-K>Y9568j(SuPBAQ){Zh0qdjZjddc38hUbXuS9WCSH95 z?>-d|VS+PTN(kU&=i6_-oy_jcYOw^^`LFBm7{DF~izycG1f4J-^w2-he+8 z4+d~=1z}{2J) k)jOloQk!O@#iFqRV|rWD)-&KeN(mFphqhj0)v{TJKPU);KL7v# literal 0 HcmV?d00001 diff --git a/extracters/ods2/wnaspi32.h b/extracters/ods2/wnaspi32.h new file mode 100644 index 0000000..b03f625 --- /dev/null +++ b/extracters/ods2/wnaspi32.h @@ -0,0 +1,376 @@ +// + +// Name: WNASPI32.H + +// + +// Description: ASPI for Win32 definitions ('C' Language) + +// + +//*************************************************************************** + + + +#ifdef __cplusplus + +extern "C" { + +#endif + + + +typedef void *LPSRB; + +typedef void (*PFNPOST)(); + + + +DWORD SendASPI32Command (LPSRB); + +DWORD GetASPI32SupportInfo (VOID); + + + +#define SENSE_LEN 14 // Default sense buffer length + +#define SRB_DIR_IN 0x08 // Transfer from SCSI target to + + // host + +#define SRB_DIR_OUT 0x10 // Transfer from host to SCSI + + // target + +#define SRB_POSTING 0x01 // Enable ASPI posting + +#define SRB_EVENT_NOTIFY 0x40 // Enable ASPI event notification + +#define SRB_ENABLE_RESIDUAL_COUNT 0x04 // Enable residual byte count + + // reporting + +#define SRB_DATA_SG_LIST 0x02 // Data buffer points to + + // scatter-gather list + +#define WM_ASPIPOST 0x4D42 // ASPI Post message + + + +//*************************************************************************** + +// %%% ASPI Command Definitions %%% + +//*************************************************************************** + +#define SC_HA_INQUIRY 0x00 // Host adapter inquiry + +#define SC_GET_DEV_TYPE 0x01 // Get device type + +#define SC_EXEC_SCSI_CMD 0x02 // Execute SCSI command + +#define SC_ABORT_SRB 0x03 // Abort an SRB + +#define SC_RESET_DEV 0x04 // SCSI bus device reset + +#define SC_GET_DISK_INFO 0x06 // Get Disk information + + + +//*************************************************************************** + +// %%% SRB Status %%% + +//*************************************************************************** + +#define SS_PENDING 0x00 // SRB being processed + +#define SS_COMP 0x01 // SRB completed without error + +#define SS_ABORTED 0x02 // SRB aborted + +#define SS_ABORT_FAIL 0x03 // Unable to abort SRB + +#define SS_ERR 0x04 // SRB completed with error + + + +#define SS_INVALID_CMD 0x80 // Invalid ASPI command + +#define SS_INVALID_HA 0x81 // Invalid host adapter number + +#define SS_NO_DEVICE 0x82 // SCSI device not installed + +#define SS_INVALID_SRB 0xE0 // Invalid parameter set in SRB + +#define SS_BUFFER_ALIGN 0xE1 // Buffer alignment problem + +#define SS_SECURITY_VIOLATION 0xE2 // Device access security violation + +#define SS_FAILED_INIT 0xE4 // ASPI for windows failed init + +#define SS_BUFFER_TO_BIG 0xE6 // Buffer size too big to handle! + + + +//*************************************************************************** + +// %%% Host Adapter Status %%% + +//*************************************************************************** + +#define HASTAT_OK 0x00 // Host adapter did not detect an + + // error + +#define HASTAT_SEL_TO 0x11 // Selection Timeout + +#define HASTAT_DO_DU 0x12 // Data overrun data underrun + +#define HASTAT_BUS_FREE 0x13 // Unexpected bus free + +#define HASTAT_PHASE_ERR 0x14 // Target bus phase sequence + + // failure + +#define HASTAT_TIMEOUT 0x09 // Timed out while SRB was + + // waiting to beprocessed. + +#define HASTAT_COMMAND_TIMEOUT 0x0B // While processing the SRB, the + + // adapter timed out. + +#define HASTAT_MESSAGE_REJECT 0x0D // While processing SRB, the + + // adapter received a MESSAGE + + // REJECT. + +#define HASTAT_BUS_RESET 0x0E // A bus reset was detected. + +#define HASTAT_PARITY_ERROR 0x0F // A parity error was detected. + +#define HASTAT_REQUEST_SENSE_FAILED 0x10 // The adapter failed in issuing + + // REQUEST SENSE. + + + +//*************************************************************************** + +// %%% SRB - HOST ADAPTER INQUIRY - SC_HA_INQUIRY %%% + +//*************************************************************************** + +typedef struct { + + BYTE SRB_Cmd; // ASPI command code = SC_HA_INQUIRY + + BYTE SRB_Status; // ASPI command status byte + + BYTE SRB_HaId; // ASPI host adapter number + + BYTE SRB_Flags; // ASPI request flags + + DWORD SRB_Hdr_Rsvd; // Reserved, MUST = 0 + + BYTE HA_Count; // Number of host adapters present + + BYTE HA_SCSI_ID; // SCSI ID of host adapter + + BYTE HA_ManagerId[16]; // String describing the manager + + BYTE HA_Identifier[16]; // String describing the host adapter + + BYTE HA_Unique[16]; // Host Adapter Unique parameters + + WORD HA_Rsvd1; + +} SRB_HAInquiry, *PSRB_HAInquiry; + + + +//*************************************************************************** + +// %%% SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE %%% + +//*************************************************************************** + +typedef struct { + + BYTE SRB_Cmd; // ASPI command code = SC_GET_DEV_TYPE + + BYTE SRB_Status; // ASPI command status byte + + BYTE SRB_HaId; // ASPI host adapter number + + BYTE SRB_Flags; // Reserved + + DWORD SRB_Hdr_Rsvd; // Reserved + + BYTE SRB_Target; // Target's SCSI ID + + BYTE SRB_Lun; // Target's LUN number + + BYTE SRB_DeviceType; // Target's peripheral device type + + BYTE SRB_Rsvd1; + +} SRB_GDEVBlock, *PSRB_GDEVBlock; + +//*************************************************************************** + +// %%% SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD %%% + +//*************************************************************************** + +typedef struct { + + BYTE SRB_Cmd; // ASPI command code = SC_EXEC_SCSI_CMD + + BYTE SRB_Status; // ASPI command status byte + + BYTE SRB_HaId; // ASPI host adapter number + + BYTE SRB_Flags; // ASPI request flags + + DWORD SRB_Hdr_Rsvd; // Reserved + + BYTE SRB_Target; // Target's SCSI ID + + BYTE SRB_Lun; // Target's LUN number + + WORD SRB_Rsvd1; // Reserved for Alignment + + DWORD SRB_BufLen; // Data Allocation Length + + BYTE *SRB_BufPointer; // Data Buffer Pointer + + BYTE SRB_SenseLen; // Sense Allocation Length + + BYTE SRB_CDBLen; // CDB Length + + BYTE SRB_HaStat; // Host Adapter Status + + BYTE SRB_TargStat; // Target Status + + void (*SRB_PostProc)(); // Post routine + + void *SRB_Rsvd2; // Reserved + + BYTE SRB_Rsvd3[16]; // Reserved for alignment + + BYTE CDBByte[16]; // SCSI CDB + + BYTE SenseArea[SENSE_LEN+2]; // Request Sense buffer + +} SRB_ExecSCSICmd, *PSRB_ExecSCSICmd; + + + +//*************************************************************************** + +// %%% SRB - ABORT AN SRB - SC_ABORT_SRB %%% + +//*************************************************************************** + +typedef struct { + + BYTE SRB_Cmd; // ASPI command code = SC_EXEC_SCSI_CMD + + BYTE SRB_Status; // ASPI command status byte + + BYTE SRB_HaId; // ASPI host adapter number + + BYTE SRB_Flags; // Reserved + + DWORD SRB_Hdr_Rsvd; // Reserved + + void *SRB_ToAbort; // Pointer to SRB to abort + +} SRB_Abort, *PSRB_Abort; + + + +//*************************************************************************** + +// %%% SRB - BUS DEVICE RESET - SC_RESET_DEV %%% + +//*************************************************************************** + +typedef struct { + + BYTE SRB_Cmd; // ASPI command code = SC_EXEC_SCSI_CMD + + BYTE SRB_Status; // ASPI command status byte + + BYTE SRB_HaId; // ASPI host adapter number + + BYTE SRB_Flags; // Reserved + + DWORD SRB_Hdr_Rsvd; // Reserved + + BYTE SRB_Target; // Target's SCSI ID + + BYTE SRB_Lun; // Target's LUN number + + BYTE SRB_Rsvd1[12]; // Reserved for Alignment + + BYTE SRB_HaStat; // Host Adapter Status + + BYTE SRB_TargStat; // Target Status + + void (*SRB_PostProc)(); // Post routine + + void *SRB_Rsvd2; // Reserved + + BYTE SRB_Rsvd3[32]; // Reserved + +} SRB_BusDeviceReset, *PSRB_BusDeviceReset; + + + +//*************************************************************************** + +// %%% SRB - GET DISK INFORMATION - SC_GET_DISK_INFO %%% + +//*************************************************************************** + +typedef struct { + + BYTE SRB_Cmd; // ASPI command code = SC_EXEC_SCSI_CMD + + BYTE SRB_Status; // ASPI command status byte + + BYTE SRB_HaId; // ASPI host adapter number + + BYTE SRB_Flags; // Reserved + + DWORD SRB_Hdr_Rsvd; // Reserved + + BYTE SRB_Target; // Target's SCSI ID + + BYTE SRB_Lun; // Target's LUN number + + BYTE SRB_DriveFlags; // Driver flags + + BYTE SRB_Int13HDriveInfo; // Host Adapter Status + + BYTE SRB_Heads; // Preferred number of heads translation + + BYTE SRB_Sectors; // Preferred number of sectors translation + + BYTE SRB_Rsvd1[10]; // Reserved + +} SRB_GetDiskInfo, *PSRB_GetDiskInfo; + + + +#ifdef __cplusplus + +} + +#endif +