Category : C Source Code
Archive   : WHICH.ZIP
Filename : WHICH.C
which.c -- print which file will get executed.
E.g., "which foo" will print the full pathname of
the file which would get executed if the user were
to type "foo".
This code is placed into the public domain by its author,
Robert L. Weissman, 9 September 1988.
It may be freely used, distributed, or modified. I really don't care.
How much can you care about a one evening hack?
*/
#include
#include
#include
#include
#include
#ifndef NULL
#define NULL ((void *) 0)
#endif
/* Note that the .com, .exe, .bat serch order is hardwired into
the following array. */
static const char * const suffixes[3] = {".com", ".exe", ".bat"};
static char * path = NULL;
static char ** patharray = NULL;
static int ndirs = 0;
static struct stat buf;
/* ---------------------------------------------------------------------- */
/* Copy up to nchars characters from src to dest, and lower them. */
static void
strncpyl(char * dest, const char * src, const int nchars)
{
register int i = 0;
if (dest == NULL || src == NULL || nchars < 1)
return;
while (*src && (i++ < nchars))
/* Note that since we have NOT included
`tolower' is the function, not the macro. We use the
function to avoid bad side effects due to the ++. */
*dest++ = (char) tolower(*src++);
*dest = '\0';
}
/* ---------------------------------------------------------------------- */
/* Fill array `patharray' with a list of the dirs in %PATH%. */
static void
setuppath(const char* path)
{
register char* p1 = path, * p2 = path;
register int i, nchars;
/* a quick scan for number of semicolons */
while (*p1)
if (*p1++ == ';')
++ndirs;
patharray = malloc(++ndirs * sizeof(char *));
p1 = p2; /* Start rescan. */
for (i = 0; i < ndirs; ++i) {
while (*p2 && (*p2 != ';'))
++p2;
patharray[i] = malloc((nchars = p2 - p1) + 1);
strncpyl(patharray[i], p1, nchars);
if (*p2 == '\0')
break; /* Done. */
p1 = ++p2; /* Reset pointer */
}
}
/* ---------------------------------------------------------------------- */
/* Find first file in path which satisfies .com, .exe, .bat search
rules of command.com, and put it's full pathname in `name'. Return
0 on failure, 1 on success. */
static int
which(const char * file, char * name)
{
register int i, j;
register char * savptr;
for (i = 0; i < ndirs; ++i) {
strcat(strcat(strcpy(name, patharray[i]), "\\"), file);
savptr = name + strlen(name); /* save pointer to null byte at end */
for (j = 0; j < 3; ++j) {
strcat(name, suffixes[j]);
if (stat(name, &buf) == 0)
return 1;
*savptr = '\0'; /* Truncate string to remove suffix */
} /* end of for j */
} /* end of for i */
return 0;
}
/* ---------------------------------------------------------------------- */
/* Search for `file.{com,exe,bat}' in the current directory, returning
1 with full name in `name' on success, or 0 on failure. */
static int
searchdot(const char * file, char * name)
{
register int j;
for (j = 0; j < 3; ++j) {
strcpy(name, file);
strcat(name, suffixes[j]);
if (stat(name, &buf) == 0)
return 1;
}
return 0;
}
/* ---------------------------------------------------------------------- */
/* Iterate over arguments, passing each to `searchdot' and
to `which' if %PATH% exists. */
int
main(int argc, char ** argv)
{
char name[100];
register int i;
path = getenv("PATH");
if (path == NULL) {
/* No path; just search current directory. */
for (i = 1; i < argc; ++i)
if (searchdot(argv[i], name))
printf("%s found: %s\n", argv[i], name);
else
printf("%s not found.\n", argv[i]);
}
else {
/* Got a path. search . then path. */
setuppath(path);
for (i = 1; i < argc; ++i)
if (searchdot(argv[i], name))
printf(".\\%s\n", name);
else if (which(argv[i], name))
printf("%s\n", name);
else
printf("%s not found.\n", argv[i]);
for (i = 0; i < ndirs; ++i)
free(patharray[i]);
free(patharray);
}
return 0;
}
/* End of which.c */
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/