Article View: comp.sys.amiga.tech
Article #555Re: What is my name?
From: Mike (I'll think of something ye...
Date: Fri, 21 Jul 1989 11:08
Date: Fri, 21 Jul 1989 11:08
152 lines
5461 bytes
5461 bytes
Having seen everyone's examples, I finally sat down and wrote my own.
For my uses, I needed a subroutine that handed back a "canonical" form
- i.e., one that gave me the same name every time, no matter how
invoked. Two things made this happen. One was taking the device part
of any absolute names to a lock, then using getpath() from the Lattice
library (this is basically just Lock2Path, as written by Doug) to turn
it back into a path. Thus, all path names come out with assigns, etc.
mapped out. The other step is to take any part of the file name not
handed back by getpath, and deal with occurences of "//" in the name.
There's one other Lattice library function here, findpath(). It walks
the path of a cli, and returns a lock on the first directory that
contains a file (subdirectory path) with the name of it's argument
file (subdirectory path). This is pretty trivial to derive from
which.c.
Since I was using those routines, I went ahead and wrote my preferred
function headers - ANSI prototype style. Those of you with Lattice 5.
or later should be able to just compile this. -L -dTEST to get a
binary that reports it's name in canonical form, sans those to get a
.o file with a "which" routine that will pass back that name. Those of
you with Manx will have to change it.
<mike
---------------- cut here ----------------
/*
* which - figure out where I was run from, and return the name
* of that binary.
*/
#include <dos.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <libraries/dos.h>
#include <proto/dos.h>
static int
myname(char *, char *) ;
#ifdef TEST
void
main(argc, argv) char **argv; {
char pathbuf[FMSIZE] ;
if (!which(argv[0], pathbuf)) puts("Can't find path") ;
else puts(pathbuf) ;
}
#endif
which(char *myname, char *pathbuf) {
char *ip ;
BPTR lock ;
int status ;
if (*myname != ':' && (ip = strchr(myname, ':')) != NULL) {
/*
* Absolute path, so just canonicalize that. This means we
* need to get a lock on the dev: file, and change myname
* to point at the rest of it.
*/
ip = '\0' ;
lock = Lock(myname, ACCESS_READ) ;
myname = ip + 1 ;
}
else {
/*
* Get a lock on the directory we're from, if we're in
* a directory on the path.
* N.B.: findpath returns a lock on the current directory
* if we feed it an absolute path name. Strange, but true.
*/
lock = findpath(myname) ;
if (lock == -1) {
/*
* Not on the path, so see if we're in C:
*/
sprintf(pathbuf, "c:%s", myname) ;
if (getfa(pathbuf) != -1) return 0 ;
/*
* It exists in C:. So get a lock on C:, so get a lock
* on the c: directory for later use.
*/
lock = Lock("c:", ACCESS_READ) ;
if (lock == -1) return 0 ;
}
}
/*
* At this point, lock is a lock on the directory that we were
* run from (well, one hopes that, anyway). So we turn that
* into a path name, then combine the two correctly.
*/
status = getpath(lock, pathbuf) ;
UnLock(lock) ;
if (status) return 0 ;
/*
* We now have a directory name known to be in canonical form,
* and the name of a file that isn't canonical, but can be found
* in that directory. So we canonicalize the catenation of the two.
*
* Step one: deal with ":". Note that getpath has the noxious habit
* of returning "dev", instead of the more proper "dev:". This leaves
* four cases:
*
* *myname : ?
*
* status
* true add ':' to pathbuf add ':' to pathbuf
* false ip = strchr(pathbuf, ':') add '/' to pathbuf
*
* both above need myname += 1
*
* "add x to pathbuf" means ip = memchr(pathbuf, '\0', FMSIZE)
* and *ip = x
*/
status = (ip = strchr(pathbuf, ':')) == NULL ;
if (*myname == ':' && !status) myname += 1 ;
else {
ip = strchr(pathbuf, '\0') ;
*ip = status ? ':' : '/' ;
if (*myname == ':') myname += 1 ;
}
/*
* Step two: Deal with "//" in the non-canonical path. Since
* pathbuf now holds a valid "dev:" string plus some canonical
* path from it, and myname a path from that directory down, that's
* all we have to worry about. Actually, we ought to put in a check
* for *myname == '/' && *ip == ':' (meaning we're trying to back up
* over the device), but that should never happen.
*/
for (;*myname; myname += 1)
if (*myname == '/' && *ip == '/')
/* double '/', get rid of one of them! */
while (*--ip != '/' && *ip != ':')
;
else *++ip = *myname ;
return 1 ;
}
--
Il brilgue: les toves lubricilleux Mike Meyer
Se gyrent en vrillant dans le guave, mwm@berkeley.edu
Enmimes sont les gougebosqueux, ucbvax!mwm
Et le momerade horsgrave. mwm@ucbjade.BITNET
Technical Details
Message-ID:
<26564@agate.BERKELEY.EDU>Path:
arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!apple!bloom-beacon!tut.cis.ohio-state.edu!ucbvax!agate!eris.berkeley.edu!mwmReferences:
<26385@agate.BERKELEY.EDU> <20565@cup.portal.com> <1227@atanasoff.cs.iastate.edu> <432@xdos.UUCP> <7372@cbmvax.UUCP> <433@xdos.UUCP> <26555@agate.BERKELEY.EDU>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!apple!bloom-beacon!tut.cis.ohio-state.edu!ucbvax!agate!eris.berkeley.edu!mwm From: mwm@eris.berkeley.edu (Mike (I'll think of something yet) Meyer) Newsgroups: comp.sys.amiga.tech Subject: Re: What is my name? Message-ID: <26564@agate.BERKELEY.EDU> Date: 21 Jul 89 11:08:45 GMT References: <26385@agate.BERKELEY.EDU> <20565@cup.portal.com> <1227@atanasoff.cs.iastate.edu> <432@xdos.UUCP> <7372@cbmvax.UUCP> <433@xdos.UUCP> <26555@agate.BERKELEY.EDU> Sender: usenet@agate.BERKELEY.EDU Reply-To: mwm@eris.berkeley.edu (Mike (I'll think of something yet) Meyer) Organization: Missionaria Phonibalonica Lines: 152