-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpath.c
163 lines (137 loc) · 2.95 KB
/
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
#include "main.h"
/**
* _strdup - return a copy of the string given as parameter
*
* @str : string to duplicate
*
* Return: a pointer to dynamically allocated memory containing a copy
* of a string given as parameter
*
* if string is NULL or malloc fails returns NULL
*/
char *_strdup(char *str)
{
char *ptr;
unsigned int i, j;
if (!str)
return (NULL);
for (i = 0; str[i] != '\0'; i++)
;
ptr = malloc(sizeof(char) * ++i);
if (!ptr)
return (NULL);
for (j = 0; j < i; j++)
ptr[j] = str[j];
return (ptr);
}
/**
* _strstr - locate a substring in a string
*
* @haystack: pointer to the string to be scanned for a substring
*
* @needle: pointer to the substring to search
*
* Return: a pointer to the first occurence of the substring in the string,
* else NULL
*/
char *_strstr(char *haystack, char *needle)
{
unsigned int i, j, pos;
for (i = 0; haystack[i] != '\0'; i++)
{
pos = i;
j = 0;
while (needle[j] != '\0')
{
if (needle[j] == haystack[i])
i++;
else
break;
j++;
}
if (needle[j] == '\0')
return (haystack + pos);
}
return (NULL);
}
/**
* _getenv - get the value of a environment variable
*
* @keyword: environment variable to search
*
* Return: the value of the environment variable or
* NULL if it doesn't exist
*/
char *_getenv(char *keyword)
{
char *value = NULL;
int i, lkey;
lkey = _strlen(keyword);
if (!keyword)
return (NULL);
i = 0;
/* skip the test if environ is NULL */
while (environ && environ[i] != NULL)
{
value = _strstr(environ[i], keyword);
/*
* ensure PATH is matched at the beginning of the line
* and is not followed by any character other than '='
* like PATH1=value
*/
if (value && *environ[i] == *keyword &&
*(value + lkey) == '=')
{
value = value + lkey + 1;
break;
}
i++;
}
return (value);
}
/**
* search_in_path - return the full path of an existing command
*
* @cmd: command to seach for
*
* Return: the full path of the command
*
* If the command exists in the current directory return "."
* If the full path of the command is given and exists return "."
* If the command cannot be found return NULL
*/
char *search_in_path(char *cmd)
{
int len;
struct stat st;
char *value, *path, cmd_fullpath[4096];
/*
* If the command exits in current path, it should start with "./"
* Otherwise command begins with "../" or "/"
*/
if (stat(cmd, &st) == 0 &&
(startwith(cmd, "./") || startwith(cmd, "../") || startwith(cmd, "/")))
return (_strdup("."));
if (_getenv("PATH"))
value = _strdup(_getenv("PATH"));
else
return (NULL);
path = strtok(value, ":");
while (path)
{
_strcpy(cmd_fullpath, path);
len = _strlen(cmd_fullpath);
_strcpy(cmd_fullpath + len, "/");
_strcpy(cmd_fullpath + len + 1, cmd);
if (stat(cmd_fullpath, &st) == 0)
{
path = _strdup(cmd_fullpath);
break;
}
path = strtok(NULL, ":");
}
/* free if a valid path has been found */
if (value)
free(value);
return (path);
}