home *** CD-ROM | disk | FTP | other *** search
- /* :ts=8 bk=0
- * Filesystem routines (or, How To Find A File The Hard Way)
- */
- #include <exec/types.h>
- #include <devices/trackdisk.h>
- #include "things.h"
-
- extern struct IOExtTD *diskreq;
- extern ULONG diskchangecount, *diskbuffer;
-
-
- findfile (name) /* Traverse the filesystem the hard way */
- char *name;
- {
- register int err;
- register char *b, *e;
- char str[80];
-
- strcpy (str, name);
- if (b = index (str, ':')) /* Ignore device names */
- b++;
- else
- b = str;
-
- while (*b == '/') /* Ignore leading slashes */
- b++;
- if (!*b) { /* Don't do anything if string is empty */
- notice ("Badly formed filename.");
- return (0);
- }
-
- e = b;
- MotorOn ();
- GetSector (ROOTBLOCK); /* All paths are relative to the root */
- while (e) {
- if (!*b) {
- notice ("Badly formed filename.");
- return (0);
- }
-
- if (e = index (b, '/'))
- *e = '\0';
-
- if ((err = traverse (b, hash (b))) < 0) {
- switch (err) {
- case -1:
- notice ("Badly formed path.");
- break;
- case -2:
- notice ("File not found.");
- break;
- }
- return (0);
- }
-
- if (e) {
- skip: b = e+1;
- while (*b == '/')
- b++;
- }
- }
- drawfile ();
- MotorOff ();
- return (1);
- }
-
- traverse (str, hash) /* Indirect through the disk blocks */
- char *str;
- int hash;
- {
- register int block;
- register char *file = (char *) &diskbuffer [NAME];
-
- if (diskbuffer [TYPE] == T_SHORT &&
- diskbuffer [SECONDARY_TYPE] == ST_FILE)
- /* Can't indirect out of a file */
- return (-1);
-
- strupper (str);
- block = diskbuffer [hash];
- for ever {
- if (!block)
- return (-2); /* No such file */
- GetSector ((long) block);
- /* Force null termination in case BCPL doesn't do it */
- file [*file + 1] = '\0';
- strupper (file+1); /* Force to all upper case */
- if (!strcmp (str, file+1)) /* Is this it? */
- break;
- /* This ain't it; traverse hash chain */
- block = diskbuffer [HASHCHAIN];
- }
- return (1);
- }
-
- drawfile () /* Draw file's allocated sectors */
- {
- register int i;
-
- /*
- * File control blocks are marked with pen 1, data blocks with pen 2.
- */
- marksector (diskbuffer [HEADER_KEY], 1);
-
- if (diskbuffer [TYPE] == T_SHORT &&
- diskbuffer [SECONDARY_TYPE] == ST_FILE)
- for ever {
- for (i=FH_BLOCKLIST; i>=FH_ENDLIST; i--)
- if (diskbuffer [i])
- marksector (diskbuffer [i], 2);
- if (diskbuffer [EXTENSION]) {
- marksector (diskbuffer [EXTENSION], 1);
- GetSector (diskbuffer [EXTENSION]);
- } else
- break;
- }
- }
-
- strupper (str)
- register char *str;
- {
- while (*str) {
- *str = toupper (*str);
- str++;
- }
- }
-
-
- /*
- * The following routines were stolen from an RKM example by Bob Peck and
- * hacked up a bit.
- */
-
- GetSector (sector)
- long sector;
- {
- LONG offset = sector * BLOCKSIZE;
-
- diskreq -> iotd_Req.io_Length = BLOCKSIZE;
- diskreq -> iotd_Req.io_Data = (APTR) diskbuffer;
- /* show where to put the data when read */
- diskreq -> iotd_Req.io_Command = ETD_READ;
- /* check that disk not changed before reading */
- diskreq -> iotd_Count = diskchangecount;
-
- /* convert from cylinder, head, sector to byte-offset value to get
- * right one (as dos and everyone else sees it)...*/
-
- /* driver reads one CYLINDER at a time (head does not move for
- * 22 sequential sector reads, or better-put, head doesnt move for
- * 2 sequential full track reads.)
- */
-
- diskreq -> iotd_Req.io_Offset = offset;
- DoIO (diskreq);
- return (0);
- }
-
- MotorOn()
- {
- /* TURN ON DISK MOTOR ... old motor state is returned in io_Actual */
- diskreq -> iotd_Req.io_Length = 1;
- /* this says motor is to be turned on */
- diskreq -> iotd_Req.io_Command = TD_MOTOR;
- /* do something with the motor */
- DoIO (diskreq);
- return (0);
- }
-
- MotorOff()
- {
- diskreq -> iotd_Req.io_Length = 0;
- /* says that motor is to be turned on */
- diskreq -> iotd_Req.io_Command = TD_MOTOR;
- /* do something with the motor */
- DoIO (diskreq);
- return (0);
- }
-
-
- /*
- * The following code segment was thrown at the USENET by Neil Katin.
- * Thanks, Neil.
- */
-
- hash (str)
- unsigned char *str;
- {
- int res;
- unsigned char *sp;
- unsigned c;
-
- res = strlen (str);
-
- for (sp = str; *sp; sp++) {
- c = *sp;
- if (c >= 'a' && c <= 'z')
- c = c - 'a' + 'A';
- res = ((res * 13 + c) & 0x7ff);
- }
- return (res % 72 + DIR_HASHTAB);
- }
-