Reputation: 115
I am trying to find the full path of a command someone would type in the terminal or console window. I am trying to use
getenv(PATH)
to get the ':' delimited strings of different paths the command may live in, and then use
stat()
to see if it exists in each one.
I am having trouble parsing through the returns of getenv() since I cannot use the string library.
getenv(path) returns:
PATH = /Library/Frameworks/Python.framework/Versions/3.2/bin:/Library/Frameworks/Python.framework/Versions/3.2/bin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
I am trying:
char* fullPath = getenv( "PATH" );
struct stat buffer;
int exists;
char* fileOrDirectory = usersCommand
exists = stat( file_or_dir, &buffer );
if ( exists == 0 && ( S_IFDIR & buffer.st_mode ) ) {
//dir exists
} else if ( exists == 0 && ( S_IFREG & buffer.st_mode ) ) {
//file exists
} else {
//neither exists
}
As of now I am not using my fullPath variable. As it is now is it just searching my local directory for the command?
An example command would be 'cd', or 'ls' , etc.
How can I parse through the ':' delimited string and then call stat on each one? I don't exactly understand the purpose of buffer besides having some info on the file or directory status but I feel like it should be taking another parameter so I can input what I am searching for as well as the fullPath.
Thanks
Upvotes: 1
Views: 1850
Reputation: 2010
Because string standard library functions are not allowed you need to write a string tokenizer yourself you can do something on the lines of the following code below, You might would have to refine it a little more.
Basically what we are doing here
Get the PATH
find token ':'
memcpy substring upto token -1
update the PATH
repeat until '\0'.
#define MAX_DIR_PATH_SIZE 500
char *get_directory(char **u_path, int *done)
{
int i;
char *temp = malloc(MAX_DIR_PATH_SIZE);
//handle error here
memset(temp,0,MAX_DIR_PATH_SIZE);
if(!u_path || !(*u_path))
return NULL;
int index =0 ;
for(i = 0;i <= MAX_DIR_PATH_SIZE ; i++)
{
if(index)
break;
switch((*u_path)[i]) // proximity of the brackets and * is important
{
case '\0':
*done = 1;
index = 1;
memcpy(temp,*u_path,i+1);
printf("Last substring %s\n",temp);
break;
//Search for token ': ascii = 58'
case 0x3A:
index = 1;
memcpy(temp,*u_path,i);
*u_path = *u_path+i+1;
printf("token found : %s\n",temp);
break;
default:
break;
}
}
//handle error for maximum size overlimit
return temp;
}
int main(int argc, char **argv)
{
char *fullPath = getenv( "PATH" );
char *u_path = fullPath;
struct stat buffer;
int exists;
int done = 0;
char* fileOrDirectory = NULL;
while(!done)
{
fileOrDirectory = get_directory(&u_path,&done);
printf("new path is : %s\n",u_path);
if(fileOrDirectory)
{
exists = stat( fileOrDirectory, &buffer );
if ( exists == 0 && ( S_IFDIR & buffer.st_mode ) ) {
printf("directory size %lu\n",buffer.st_size);
}
else {
//do something else
}
free(fileOrDirectory);
}
}
return 0;
}
Upvotes: 1
Reputation: 8819
The function strtok
is the standard method of tokenizing a string. With that you can build the full path-name of the file.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
main(int argc, char **argv)
{
char* fullPath = getenv( "PATH" );
struct stat buffer;
int exists;
char* fileOrDirectory = argv[0];
char fullfilename[1024];
char *token = strtok(fullPath, ":");
/* walk through other tokens */
while( token != NULL )
{
sprintf(fullfilename, "%s/%s", token, fileOrDirectory);
exists = stat( fullfilename, &buffer );
if ( exists == 0 && ( S_IFREG & buffer.st_mode ) ) {
printf("found file %s\n", fullfilename);
}
token = strtok(NULL, ":"); /* next token */
}
exit(0);
}
Upvotes: 1
Reputation: 206577
Here's something to try:
// Variables needed during iteration.
char* start = fullPath;
char sep = ':';
char* iter;
char trialPath[BUFSIZ];
// Get the path
char* originalPath = getenv( "PATH" );
// Make a copy of the path since we are going to modify it
// while we are iterating on it.
char* fullPath = malloc(strlen(originalPath) + 1);
strcpy(fullPath, originalPath);
start = fullPath;
// Iterate over the path.
for ( char* iter = start; *iter != '\0'; ++iter )
{
if ( *iter == sep )
{
*iter = '\0';
// Now, start is a directory.
// Check whether the user command is at this location.
strcpy(trialPath, start);
strcat(trialPath, "/");
strcat(trialPath, usersCommand);
// Now use stat to check whether the file exists and
// it is an executable.
// ....
// If not, reset where start points to.
start = iter + 1;
}
}
// Deallocate memory allocated earliner.
free(fullPath);
Upvotes: 0