-
Notifications
You must be signed in to change notification settings - Fork 0
/
PATH_search.c
77 lines (65 loc) · 1.96 KB
/
PATH_search.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
#include "shell.h"
/**
* can_execute - checks if a string represents an executable path
* @command: string containing the command to check
* Return: 0 on sucess, 127 if file does not exist
* 126 if file exists but cannot be executed
*/
int can_execute(char *command)
{
char *error_message;
int DENIED = 126, NOTFOUND = 127, SUCCESS = 0;
if (access(command, X_OK) == 0)
return (SUCCESS);
else if (access(command, F_OK) == 0)
{ /* File exists but cannot be executed */
error_message = _strmerge(2, command, ": Permission denied\n");
print_error(error_message);
free(error_message);
return (DENIED);
}
else
return (NOTFOUND);
}
/**
* PATH_search - searches the path for the input command
* @input_ll_p: address of linked list containing input command
* Return: 0 on sucess, 127 if nothing found
*/
int PATH_search(list_t **input_ll_p)
{
int NOTFOUND = 127, DENIED = 126, SUCCESS = 0, access_code;
char *buff, *error_message;
list_t *new_node, *path_ll, *path_ll_head, *input_ll = *input_ll_p;
if (!input_ll)
return (NOTFOUND);
/* check if input is a valid path which can be directly executed */
access_code = can_execute(input_ll->str);
if (access_code == SUCCESS)
return (SUCCESS);
else if (access_code == DENIED)
return (DENIED);
/* creates a dymanic path linked list */
path_ll_head = split_str(get_env_var("PATH="), ":=");
for (path_ll = path_ll_head; path_ll; path_ll = path_ll->next)
{ /* Merge path and command */
buff = _strmerge(3, path_ll->str, "/", input_ll->str);
/* using stat to run a search */
if (access(buff, F_OK) == 0)
{ /* replaces first input_ll with buffer */
new_node = input_ll->next;
free(input_ll->str);
free(input_ll);
*input_ll_p = add_node(&new_node, buff);
free(buff);
free_list(path_ll_head);
return (SUCCESS);
}
free(buff);
}
free_list(path_ll_head);
error_message = _strmerge(2, input_ll->str, ": not found\n");
print_error(error_message);
free(error_message);
return (NOTFOUND);
}