tiny-shell 0.2
A mini shell project aiming to gain knowledge about Win32 and Linux API
Loading...
Searching...
No Matches
add_path.c
Go to the documentation of this file.
1#include "add_path.h"
2#include "../core/io_wrap.h"
3#include "../os/operations.h"
4#include <limits.h>
5#include <stdlib.h>
6#include <string.h>
7
8#ifdef _WIN32
9# define SEPARATOR ";"
10
11os_char *formatted_path(const os_char *path) {
12 os_char *f_path = (os_char *)malloc((strlen(path) + 2) * sizeof(os_char));
13 size_t len = strlen(path);
14 strncpy(f_path, path, strlen(path));
15 f_path[len] = '\0';
16 strncat(f_path, SEPARATOR, 2);
17 return f_path;
18}
19
20#elif defined(__linux__)
21# define SEPARATOR ":"
22
23os_char *formatted_path(const os_char *path) {
24 os_char *f_path = (os_char *)malloc((strlen(path) + 2) * sizeof(os_char));
25 strncpy(f_path, SEPARATOR, 1);
26 f_path[1] = '\0';
27 strncat(f_path, path, strlen(path));
28 return f_path;
29}
30
31#endif
32
33char *strtok_r_custom(char *str, const char *delim, char **saveptr) {
34 char *token = NULL;
35 if(str == NULL) {
36 str = *saveptr;
37 }
38 // Skip leading delimiters
39 str += strspn(str, delim);
40 if(*str == '\0') {
41 return NULL;
42 }
43 // Find the end of the token
44 token = str;
45 str = strpbrk(token, delim);
46 if(str == NULL) {
47 // This token finishes the string
48 *saveptr = strchr(token, '\0');
49 } else {
50 // Terminate the token and update the save pointer
51 *str = '\0';
52 *saveptr = str + 1;
53 }
54 return token;
55}
56
57bool in_path_env(const os_char *path_env, const os_char *new_path) {
58 size_t len = strlen(path_env);
59 os_char tmp_path_env[SHRT_MAX];
60 strncpy(tmp_path_env, path_env, len);
61 tmp_path_env[len] = '\0';
62
63 char *rest = NULL;
64 char *token = strtok_r_custom(tmp_path_env, SEPARATOR, &rest);
65 while(token != NULL) {
66 if(!strcmp(token, new_path)) {
67 return true;
68 }
69 token = strtok_r_custom(NULL, SEPARATOR, &rest);
70 }
71 return false;
72}
73
74bool add_path(const os_char *new_path) {
75 char buffer[SHRT_MAX];
76 unsigned int bufferSize = sizeof(buffer) / sizeof(char);
77
78 if(!get_shell_env("PATH", bufferSize, buffer)) {
79 format_error("Fail to get PATH environment variable!\n");
80 return false;
81 }
82
83 if(in_path_env(buffer, new_path)) {
84 format_error("The path %s is already in the PATH environment variable.\n", new_path);
85 return false;
86 }
87
88 os_char *f_path = formatted_path(new_path);
89 strncat(buffer, f_path, strlen(f_path));
90
91 if(!set_shell_env("PATH", buffer)) {
92 format_error("Failed to set the PATH environment variable!\n");
93 free(f_path);
94 return false;
95 }
96 format_success("PATH environment variable is updated successfully.\n");
97 free(f_path);
98 return true;
99}
100
101enum run_result run_add_path(const os_char *new_path) {
102 return add_path(new_path) ? RUN_OK : RUN_FAILED;
103}
char * strtok_r_custom(char *str, const char *delim, char **saveptr)
Definition add_path.c:33
bool in_path_env(const os_char *path_env, const os_char *new_path)
Definition add_path.c:57
bool add_path(const os_char *new_path)
Definition add_path.c:74
enum run_result run_add_path(const os_char *new_path)
Definition add_path.c:101
void format_success(char *fmt,...)
Used format_xxx instead of printf and such for uniform output.
Definition io_wrap.c:69
void format_error(char *fmt,...)
Used format_xxx instead of printf and such for uniform output.
Definition io_wrap.c:89
bool get_shell_env(const os_char *var, unsigned int buffer_size, os_char *buffer)
Get value of an an environment variable.
bool set_shell_env(const os_char *name, const os_char *val)
Set environment variable of the shell process.
run_result
Result of the execution of a command line.
Definition res.h:6
@ RUN_OK
Definition res.h:7
@ RUN_FAILED
Definition res.h:9