Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.milw.wisc.edu!cs.utexas.edu!usc!apple!motcsd!xdos!doug From: doug@xdos.UUCP (Doug Merritt) Newsgroups: comp.sys.amiga.tech Subject: Re: What is my name? Summary: Full solution enclosed: whence.c Message-ID: <433@xdos.UUCP> Date: 20 Jul 89 21:07:59 GMT References: <26385@agate.BERKELEY.EDU> <20565@cup.portal.com> <1227@atanasoff.cs.iastate.edu> <432@xdos.UUCP> <7372@cbmvax.UUCP> Reply-To: doug@xdos.UUCP (Doug Merritt) Organization: Hunter Systems, Mountain View CA (Silicon Valley) Lines: 211 In article <7372@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes: >In article <432@xdos.UUCP> doug@xdos.UUCP (Doug Merritt) writes: >>But in this case the full path is in argv[0], making this the easiest >>of the solutions. >> if (!argc) >> look at WBenchMsg >> else if (any {':','/'} in argv[0]) >> use argv[0] >> else >> use PATH > > That should work (though it is painful) under 1.2/1.3. I thought of >that one 5 minutes after I posted my other response. Glad to see someone >beat me to it. Yeah, and even aside from the complexity, it's painful to have to look things up in the PATH...inelegant, since it's sort of guessing. But Josh Rovero pointed out that cli_CommandName has what we need, which made things easier and more robust, so I put together a full solution based on that idea and some code I already had lying around (this made it possible for me to go from start to finish in 1 hour). Hope it's useful. Doug Doug Merritt {pyramid,apple}!xdos!doug Member, Crusaders for a Better Tomorrow Professional Wildeyed Visionary --------------------- CUT HERE ----- CUT HERE ------- CUT HERE ------------- /* * whence -- Example program: show full path of executable the current * process was launched from. Works under both CLI and Workbench. * * Thanks to Josh Rovero for pointing out that the info needed for * working under CLI was available in cli_CommandName. * * Written because Mike Meyer wanted it. Happy to oblige, Mike. */ /* * Copyright 1989 Doug Merritt. License to use hereby granted. * {pyramid,apple}!xdos!doug * (408) 370-7875 */ /* * Compiled under Manx Aztec C V3.6A * cc -Iinclude: whence.c * ln -o whence whence.o -lc * * Note use of BufRound() macro instead of allocated memory; this * is widely useful. * Also the Lock2Path() function is very handy. * * Bugs: when called from workbench, or relative to current directory, * the device name is shown, but when called via absolute path from CLI, * the ASSIGN'ed name is shown (e.g. "mydisk:" rather than "df0:"). * I have a function that'll fix that (i.e. convert assign names to * device names), if anyone wants it let me know. * * Please retain my copyright notice if/when you borrow this code. */ #include "libraries/dos.h" #include "libraries/dosextens.h" #include "workbench/startup.h" #include "stdio.h" /* * RoundUp0 -- ceiling (yields 0 if n % TO == 0) * BufRound -- given buffer address, rounds up to word boundary */ #define RoundUp0(N,TO) ( (TO - (((ULONG)N) & (TO-1)) ) & (TO-1)) #define BufRound(BUF) &BUF[ RoundUp0(BUF,4) ] char * bstr2str(d, bs) char *d; unsigned long bs; { char *s; int len; s = (char *) (bs << 2); len = *s++ & 0xff; while (len-- > 0) *d++ = *s++; *d = '\0'; } Lock2Path(curlock, pathbuf) struct FileLock *curlock; char *pathbuf; { #define LOCKSTACKSIZE 128 struct FileLock *locklist[LOCKSTACKSIZE]; UBYTE Ibuf [ sizeof(struct FileInfoBlock) + 4]; struct FileInfoBlock *Ifib; int i; char *s, *path; extern struct FileLock *ParentDir(); Ifib = (struct FileInfoBlock *) BufRound(Ibuf); if (!Examine(curlock, Ifib)) return(0); /* * find full path name; build LIFO stack of * pushed locks; when full use popped locks with * Examine() to get each name in path. */ for (i=0; i= LOCKSTACKSIZE) { printf("Too many subdirectories\n"); *path++ = '?'; *path++ = '/'; --i; } /* * concatenate each component of path */ if (!Examine(locklist[i--], Ifib)) goto wierd; for (s=Ifib->fib_FileName; *s; ) *path++ = *s++; *path++ = ':'; while (i >= 0) { if (!Examine(locklist[i], Ifib)) goto wierd; for (s=Ifib->fib_FileName; *s; ) *path++ = *s++; if (i>0) *path++ = '/'; --i; } *path = '\0'; return(path - &pathbuf[0]); wierd: *path++ = '?'; *path++ = '/'; *path = '\0'; return(path - &pathbuf[0]); } /* Lock2Path() */ /* * get head of path by chopping off tail (delete anything after : or /) */ head(s) char *s; { char *start; if (!*s) return(0); start = s; while (*s) ++s; while (*s != ':' && *s != '/') { if (s == start) return(0); --s; } *++s = '\0'; return(1); } main(argc, argv) int argc; char **argv; { struct Process *proc; struct CommandLineInterface *cli; extern struct Process *FindTask(); extern struct WBStartup *WBenchMsg; extern struct FileLock *Lock(); char buf[256]; FILE *f; if (!argc) { if ((f = fopen("CON:0/0/640/200/whence", "w")) == NULL) exit(20); if (!Lock2Path(WBenchMsg->sm_ArgList[0].wa_Lock, buf)) { fprintf(f, "Error\n"); Delay(150L); exit(10); } fprintf(f, "%s\n", buf); Delay(150L); fclose(f); exit(0); } else { proc = (struct Process *) FindTask(0L); cli = (struct CommandLineInterface *) ( ((long) proc->pr_CLI) << 2); bstr2str(buf, cli->cli_CommandName); if (!head(buf)) { /* launched relative to current dir? */ struct FileLock *lock; lock = Lock("", ACCESS_READ); if (!Lock2Path( lock, buf)) { UnLock(lock); printf("No current dir?\n"); exit(10); } UnLock(lock); } printf("%s\n", buf); } } -- Doug Merritt {pyramid,apple}!xdos!doug Member, Crusaders for a Better Tomorrow Professional Wildeyed Visionary