-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathfind_path.c
177 lines (161 loc) · 4.01 KB
/
find_path.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include "olaf.h"
/**
* path_finder - Acts as an interface for functions that will be able to
* find the full path of a program.
* @command: Represents a command. For example ls, echo, pwd, etc.
* Return: Upon sucess a string with the full path of the program.
* for example /bin/ls, /bin/echo, etc. Otherwise returns NULL.
*/
char *path_finder(char *command)
{
char *str = "PATH";
char *constructed;
char **path_tokens;
int index;
char *directory;
index = find_path(str);
path_tokens = tokenize_path(index, str);
if (path_tokens == NULL)
return (NULL);
directory = search_directories(path_tokens, command);
if (directory == NULL)
{
double_free(path_tokens);
return (NULL);
}
constructed = build_path(directory, command);
if (constructed == NULL)
{
double_free(path_tokens);
return (NULL);
}
double_free(path_tokens);
return (constructed);
}
/**
* find_path - Finds the index of an environmental variable.
* @str: Environmental variable that needs to be found.
* Return: Upon success returns the index of the environmental variable.
* otherwise returns -1.
*/
int find_path(char *str)
{
int i;
int len;
int j;
len = str_len(str);
for (i = 0; environ[i] != NULL; i++)
{
for (j = 0; j < len; j++)
{
if (environ[i][j] != str[j])
break;
}
if (j == len && environ[i][j] == '=')
return (i);
}
return (-1);
}
/**
* tokenize_path - Separates a string representing paths as an array
* of strings contining the path directories.
* @index: Index of the path in the environment variables.
* @str: string to separate and tokenize.
* Return: Upon success a NULL terminated array of pointer to strings.
* Otherwise returns NULL. Note!: Do not forget to free alocated
* memory on receiving function or when possible.
*/
char **tokenize_path(int index, char *str)
{
char *env_var;
int token_count;
const char *delim = ":\n";
char **path_tokens;
int len;
len = str_len(str);
token_count = 0;
/*Moving the pointer len of str plus = sign*/
env_var = environ[index] + (len + 1);
path_tokens = token_interface(env_var, delim, token_count);
if (path_tokens == NULL)
return (NULL);
return (path_tokens);
}
/**
* search_directories - Looks through directories stored in path_tokens for a
* specific file. aka commmand.
* @path_tokens: A pointer to an array of strings representing the different
* paths contained in the PATH environmental varible.
* @command: Represents a command. For example ls, echo, pwd, /bin/ls etc.
* Return: Upon success a string with the upper most directory containing
* the command file. Otherwise returns NULL.
*/
char *search_directories(char **path_tokens, char *command)
{
int i, s;
char *cwd;
char *buf;
size_t size;
struct stat stat_buf;
buf = NULL;
size = 0;
cwd = getcwd(buf, size);
if (cwd == NULL)
return (NULL);
if (command[0] == '/')
command = command + 1;
for (i = 0; path_tokens[i] != NULL; i++)
{
s = chdir(path_tokens[i]);
if (s == -1)
{
perror("ERROR!");
return (NULL);
}
s = stat(command, &stat_buf);
if (s == 0)
{
chdir(cwd);
free(cwd);
return (path_tokens[i]);
}
}
chdir(cwd);
free(cwd);
return (NULL);
}
/**
* build_path - Combines two strings one representing the path directory and
* one representing the command file.
* @directory: Represents a directory in the path.
* @command: Represents a file in a directory of the path.
* Return: Upon success a string representing the full path of a command.
* Otherwise NULL.
*/
char *build_path(char *directory, char *command)
{
int i, j;
int dir_len;
int command_len;
int len;
char *built;
if (directory == NULL || command == NULL)
return (NULL);
dir_len = str_len(directory) + 1;
command_len = str_len(command) + 1;
len = dir_len + command_len;
built = malloc(sizeof(char) * len);
if (built == NULL)
return (NULL);
for (i = 0; i < len; i++)
{
for (j = 0; directory[j] != '\0'; j++, i++)
built[i] = directory[j];
built[i] = '/';
i++;
for (j = 0; command[j] != '\0'; j++, i++)
built[i] = command[j];
}
built[--i] = '\0';
return (built);
}