home *** CD-ROM | disk | FTP | other *** search
- #include "dos.h"
-
- extern PORT *DosPort; /* Our DOS port... this is slick... */
- extern PROC *DosProc; /* Our Process */
- extern DEVNODE *DosNode; /* Our DOS node.. created by DOS for us */
- extern DEVLIST *DevList; /* Device List structure for our volume node */
- extern void *SysBase; /* EXEC library base */
- extern DOSLIB *DOSBase; /* DOS library base for debug process */
- extern RAMFILE RFRoot; /* Directory/File structure (root node) */
- extern LIST FHBase; /* Open Files */
- extern LIST LCBase; /* Open Locks */
- extern long TotalBytes; /* total bytes of data in filesystem */
- extern RAMFILE xpath; /* This is used in case of off device path */
- extern char *buf1; /* This holds the translated path names */
-
- RAMFILE * checkoutpath();
- RAMFILE * vsearchpath();
- void *DeviceProc();
-
- /*
- * PACKET ROUTINES. Dos Packets are in a rather strange format as you
- * can see by this and how the PACKET structure is extracted in the
- * GetMsg() of the main routine.
- */
-
- void
- returnpacket(packet)
- register struct DosPacket *packet;
- {
- register struct Message *mess;
- register struct MsgPort *replyport;
-
- replyport = packet->dp_Port;
- mess = packet->dp_Link;
- packet->dp_Port = DosPort;
- mess->mn_Node.ln_Name = (char *)packet;
- mess->mn_Node.ln_Succ = NULL;
- mess->mn_Node.ln_Pred = NULL;
- PutMsg(replyport, mess);
- }
-
- /*
- * Are there any packets queued to our device?
- */
-
- packetsqueued()
- {
- return ((void *)DosPort->mp_MsgList.lh_Head !=
- (void *)DosPort->mp_MsgList.lh_Tail);
- }
-
- /*
- * DOS MEMORY ROUTINES
- *
- * DOS makes certain assumptions about LOCKS. A lock must minimally be
- * a FileLock structure, with additional private information after the
- * FileLock structure. The longword before the beginning of the structure
- * must contain the length of structure + 4.
- *
- * NOTE!!!!! The workbench does not follow the rules and assumes it can
- * copy lock structures. This means that if you want to be workbench
- * compatible, your lock structures must be EXACTLY sizeof(struct FileLock).
- */
-
- void *
- dosalloc(bytes)
- register ulong bytes;
- {
- register ulong *ptr;
-
- bytes += 4;
- ptr = AllocMem(bytes, MEMF_PUBLIC|MEMF_CLEAR);
- *ptr = bytes;
- return(ptr+1);
- }
-
- dosfree(ptr)
- register ulong *ptr;
- {
- --ptr;
- FreeMem(ptr, *ptr);
- }
-
- /*
- * Convert a BSTR into a normal string.. copying the string into buf.
- * I use normal strings for internal storage, and convert back and forth
- * when required.
- */
-
- void
- btos(bstr,buf)
- ubyte *bstr;
- ubyte *buf;
- {
- bstr = BTOC(bstr);
- bmov(bstr+1,buf,*bstr);
- buf[*bstr] = 0;
- }
-
- /*
- * Some EXEC list handling routines not found in the EXEC library.
- */
-
- void *
- NextNode(node)
- NODE *node;
- {
- node = node->mln_Succ;
- if (node->mln_Succ == NULL)
- return(NULL);
- return(node);
- }
-
- void *
- GetHead(list)
- LIST *list;
- {
- if ((void *)list->mlh_Head != (void *)&list->mlh_Tail)
- return(list->mlh_Head);
- return(NULL);
- }
-
- /*
- * Compare two names which are at least n characters long each,
- * ignoring case.
- */
-
- nccmp(p1,p2,n)
- register ubyte *p1, *p2;
- register short n;
- {
- while (--n >= 0) {
- if ((p1[n]|0x20) != (p2[n]|0x20))
- return(0);
- }
- return(1);
- }
-
- /*
- * Create a file or directory and link it into it's parent directory.
- */
-
- RAMFILE *
- createramfile(parentdir, type, name)
- RAMFILE *parentdir;
- char *name;
- {
- register RAMFILE *ramfile;
-
- ramfile = AllocMem(sizeof(RAMFILE), MEMF_CLEAR|MEMF_PUBLIC);
- AddTail(&parentdir->list, ramfile);
- ramfile->parent = parentdir;
- ramfile->name = AllocMem(strlen(name)+1, MEMF_PUBLIC);
- strcpy(ramfile->name, name);
- ramfile->type = type;
- ramfile->protection = 0;
- NewList(&ramfile->list);
- DateStamp(&ramfile->date);
- DateStamp(&ramfile->parent->date);
- return(ramfile);
- }
-
- /*
- * Free all data associated with a file
- */
-
- void
- freedata(ramfile)
- RAMFILE *ramfile;
- {
- FENTRY *fen;
-
- TotalBytes -= ramfile->bytes;
- while (fen = RemHead(&ramfile->list)) {
- /*DB*/ dbprintf("FREE FEN: %08lx %08lx %ld\n", fen, fen->buf, fen->bytes);
- FreeMem(fen->buf, fen->bytes);
- FreeMem(fen, sizeof(*fen));
- }
- ramfile->bytes = 0;
- DateStamp(&ramfile->date);
- DateStamp(&ramfile->parent->date);
- }
-
- /*
- * Unlink and remove a file. Any data associated with the file or
- * directory has already been freed up.
- */
-
- void
- freeramfile(ramfile)
- RAMFILE *ramfile;
- {
- Remove(ramfile); /* unlink from parent directory */
- if (ramfile->name)
- FreeMem(ramfile->name,strlen(ramfile->name)+1);
- if (ramfile->comment)
- FreeMem(ramfile->comment,strlen(ramfile->comment)+1);
- FreeMem(ramfile,sizeof(*ramfile));
- }
-
- /*
- * The lock function. The file has already been checked to see if it
- * is lockable given the mode.
- */
-
- LOCK *
- ramlock(ramfile, mode)
- RAMFILE *ramfile;
- {
- LOCK *lock = dosalloc(sizeof(LOCK));
- LOCKLINK *ln;
-
- if (mode != ACCESS_WRITE)
- mode = ACCESS_READ;
- ln = AllocMem(sizeof(LOCKLINK), MEMF_PUBLIC);
- AddHead(&LCBase,ln);
- ln->lock = lock;
- lock->fl_Link= (long)ln;
- lock->fl_Key = (long)ramfile;
- lock->fl_Access = mode;
- lock->fl_Task = DosPort;
- lock->fl_Volume = (BPTR)CTOB(DosNode);
- if (mode == ACCESS_READ)
- ++ramfile->locks;
- else
- ramfile->locks = -1;
- return(lock);
- }
-
- void
- ramunlock(lock)
- LOCK *lock;
- {
- RAMFILE *file = (RAMFILE *)lock->fl_Key;
-
- Remove(lock->fl_Link); /* unlink from list */
- FreeMem(lock->fl_Link, sizeof(LOCKLINK)); /* free link node */
- if (lock->fl_Access == ACCESS_READ) /* undo lock effect */
- --file->locks;
- else
- file->locks = 0;
- dosfree(lock); /* free lock */
- }
-
- /*
- * GETLOCKFILE(bptrlock)
- *
- * Return the RAMFILE entry (file or directory) associated with the
- * given lock, which is passed as a BPTR.
- *
- * According to the DOS spec, the only way a NULL lock will ever be
- * passed to you is if the DosNode->dn_Lock is NULL, but I'm not sure.
- * In anycase, If a NULL lock is passed to me I simply assume it means
- * the root directory of the RAM disk.
- */
-
- RAMFILE *
- getlockfile(lock)
- void *lock; /* actually BPTR to LOCK */
- {
- register LOCK *rl = BTOC(lock);
-
- if (rl) return((RAMFILE *)rl->fl_Key);
- return(&RFRoot);
- }
-
- /*
- * Search the specified path beginning at the specified directory.
- * The directory pointer is updated to the directory containing the
- * actual file. Return the file node or NULL if not found. If the
- * path is illegal (an intermediate directory was not found), set *ppar
- * to NULL and return NULL.
- *
- * *ppar may also be set to NULL if the search path IS the root.
- *
- * If pptr not NULL, Set *pptr to the final component in the path.
- */
-
- char *rindex();
-
- RAMFILE *
- searchpath(ppar,buf,pptr)
- RAMFILE **ppar;
- char *buf;
- char **pptr;
- {
- RAMFILE *file = *ppar;
- RAMFILE *srch;
- short len;
- char *ptr;
-
- ptr = rindex(buf,':');
- if (ptr) buf = ptr+1;
-
- *ppar = NULL;
- for (;*buf && file;) {
- ptr = getpathelement(&buf,&len);
- if (*ptr == '/') { /* go back a directory */
- if (!file->parent) { /* no parent directory */
- return(NULL);
- }
- file = file->parent;
- continue;
- }
- if (file->type == FILE_FILE)
- return(checkoutpath(file,ptr));
- for (srch = GetHead(&file->list); srch; srch = NextNode(srch)) {
- if (srch->type && strlen(srch->name) == len && nccmp(srch->name, ptr, len)) {
- file = srch; /* element found */
- break;
- }
- }
- if (srch == NULL) {
- if (*buf == 0) /* Element not found. If it was the final */
- *ppar = file; /* element the parent directory is valid */
- if (pptr)
- *pptr = ptr;
- return(NULL);
- }
- }
- if (pptr)
- *pptr = ptr;
- *ppar = file->parent;
- return(file);
- }
-
- RAMFILE *
- vsearchpath(ppar,buf,pptr)
- RAMFILE **ppar;
- char *buf;
- char **pptr;
- {
- RAMFILE *file = *ppar;
- RAMFILE *srch;
- short len;
- char *ptr;
-
- ptr = rindex(buf,':'); /* this fixes up the colon treatment */
- if (ptr) buf = ptr+1;
-
- *ppar = NULL;
- for (;*buf && file;) {
- ptr = getpathelement(&buf,&len);
- if (*ptr == '/') { /* go back a directory */
- if (!file->parent) { /* no parent directory */
- return(NULL);
- }
- file = file->parent;
- continue;
- }
- if (file->type == FILE_FILE)
- return(NULL);
- for (srch = GetHead(&file->list); srch; srch = NextNode(srch)) {
- if (srch->type && strlen(srch->name) == len && nccmp(srch->name, ptr, len)) {
- file = srch; /* element found */
- break;
- }
- }
- if (srch == NULL) {
- if (*buf == 0) /* Element not found. If it was the final */
- *ppar = file; /* element the parent directory is valid */
- if (pptr)
- *pptr = ptr;
- return(NULL);
- }
- }
- if (pptr)
- *pptr = ptr;
- *ppar = file->parent;
- return(file);
- }
- typedef struct {
- FENTRY *fentry;
- long offset;
- } SFH; /* simple file handle */
-
- RAMFILE *
- checkoutpath(file,path)
- RAMFILE *file;
- char *path;
- {
- SFH fh;
- int lck;
-
- fh.fentry = GetHead(&file->list);
- fh.offset = 0;
- while (getnexttry(&fh,buf1)) {
- strcat(buf1,path);
- if (DeviceProc(buf1) == DosPort) {
- /* refers to us.. ignore */
- continue;
- }
- if (!index(buf1,':')) {
- /* not an absolute path */
- continue;
- }
- if (lck = Lock(buf1,ACCESS_READ)) {
- UnLock(lck);
- return(&xpath);
- }
- }
- return(0);
- }
-
- getnexttry(fh,buf)
- register SFH *fh;
- register char *buf;
- {
- register int i;
- register FENTRY *fe;
-
- fe = fh->fentry;
- i = fh->offset;
-
- for (fe = fh->fentry; fe ; fe = NextNode(fe)) {
- for (; i<fe->bytes; i++) {
- *buf = fe->buf[i];
- if (*buf == '\n') {
- *buf = 0;
- fh->fentry = fe;
- fh->offset = ++i;
- return(1);
- }
- buf++;
- }
- i=0;
- }
- return(0);
- }
-
-
- /*
- * Return the next path element in the string. The routine effectively
- * removes any trailing '/'s, but treats ':' as part of the next component
- * (i.e. ':' is checked and skipped in SEARCHPATH()).
- */
-
- char *
- getpathelement(pstr,plen)
- char **pstr;
- short *plen;
- {
- char *base;
- register char *ptr = *pstr;
- register short len = 0;
-
- if (*(base = ptr)) {
- if (*ptr == '/') {
- ++ptr;
- ++len;
- } else {
- while (*ptr && *ptr != '/') {
- ++ptr;
- ++len;
- }
- if (*ptr == '/')
- ++ptr;
- }
- }
- *pstr = ptr;
- *plen = len;
- return(base);
- }
-
-
- char *
- typetostr(ty)
- {
- switch(ty) {
- case ACTION_DIE: return("DIE");
- case ACTION_OPENRW: return("OPEN-RW");
- case ACTION_OPENOLD: return("OPEN-OLD");
- case ACTION_OPENNEW: return("OPEN-NEW");
- case ACTION_READ: return("READ");
- case ACTION_WRITE: return("WRITE");
- case ACTION_CLOSE: return("CLOSE");
- case ACTION_SEEK: return("SEEK");
- case ACTION_EXAMINE_NEXT: return("EXAMINE NEXT");
- case ACTION_EXAMINE_OBJECT: return("EXAMINE OBJ");
- case ACTION_INFO: return("INFO");
- case ACTION_DISK_INFO: return("DISK INFO");
- case ACTION_PARENT: return("PARENTDIR");
- case ACTION_DELETE_OBJECT: return("DELETE");
- case ACTION_CREATE_DIR: return("CREATEDIR");
- case ACTION_LOCATE_OBJECT: return("LOCK");
- case ACTION_COPY_DIR: return("DUPLOCK");
- case ACTION_FREE_LOCK: return("FREELOCK");
- case ACTION_SET_PROTECT: return("SETPROTECT");
- case ACTION_SET_COMMENT: return("SETCOMMENT");
- case ACTION_RENAME_OBJECT: return("RENAME");
- case ACTION_INHIBIT: return("INHIBIT");
- case ACTION_RENAME_DISK: return("RENAME DISK");
- case ACTION_MORECACHE: return("MORE CACHE");
- case ACTION_WAIT_CHAR: return("WAIT FOR CHAR");
- case ACTION_FLUSH: return("FLUSH");
- case ACTION_RAWMODE: return("RAWMODE");
- default: return("---------UNKNOWN-------");
- }
- }
-
-