-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vipshell.c
197 lines (166 loc) · 6.33 KB
/
vipshell.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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*
▒█░░▒█ ░▀░ █▀▀█ ▒█▀▀▀█ █░░█ █▀▀ █░░ █░░
░▒█▒█░ ▀█▀ █░░█ ░▀▀▀▄▄ █▀▀█ █▀▀ █░░ █░░
░░▀▄▀░ ▀▀▀ █▀▀▀ ▒█▄▄▄█ ▀░░▀ ▀▀▀ ▀▀▀ ▀▀▀
*************************************
Shell Vip Utility written in C for *NX Systems
*************************************
* Simple: Vip shell to avoid usage of sudo
*************************************
* Developed and engineered by
* Felipe Alfonso gonzalez <[email protected]>
* Under MIT - BSD 3 - Restrictive
*************************************
* gunzip vip.c.gz
* gcc -o vip vip.c (compilation)
* su
* vi /etc/group (nuevo grupo, ej.: staff:x:100:user)
* mv vip /usr/bin/
* exit
* vip
*
* */
/*
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <stddef.h>
*/
// # include <strcat.h>
/*
Included necessary header files
(unistd.h and sys/wait.h) for functions like setuid, setgid, fork, and wait.
Added proper return type and parameter types to the main function.
Fixed the comment syntax (removed leading spaces before #include and #define).
Replaced exit(0) with return 0 at the end of main function.
Replaced the hardcoded value "q" with a proper condition in the if statement.
Removed the duplicated fprintf(stderr, "Vip Shell Ending.\n");
line after the if-else statement.
In this modified code, after checking if argc < 2, it prompts the user with
a question asking if they want to run the program. It waits for the user's input
(either 'Y' or 'y' for yes), and if the input is not 'Y' or 'y', it aborts
the program execution.
In this modified code, after checking if argc < 2, it asks the user two questions
to run the code as sudo, but must be restarted the shell as sudo.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#define MAXLENCMD 1024 * 6
#define MAXHISTORY 20
void print_vip_prompt(char *cwd) {
// Display the current working directory name
char *lastSlash = strrchr(cwd, '/');
char *dirName = lastSlash ? lastSlash + 1 : cwd;
printf("[VipShell] %s //> ", dirName);
fflush(stdout);
}
void execute_command(char *cmd) {
int pid, rc, p;
if ((pid = fork()) == -1) {
fprintf(stderr, "Fork Failed.\n");
exit(1);
} else if (pid == 0) {
execl("/bin/bash", "bash", "-c", cmd, NULL);
fprintf(stderr, "Failed to execute command: %s\n", cmd);
exit(1);
} else {
while ((p = wait(&rc)) != -1 && p != pid);
}
}
void display_last_commands(char history[MAXHISTORY][MAXLENCMD + 1]) {
printf("Last Commands:\n");
for (int i = 0; i < MAXHISTORY; i++) {
if (strlen(history[i]) > 0) {
printf("%d: %s\n", i + 1, history[i]);
}
}
}
void display_last_files(char *files[MAXHISTORY]) {
printf("Last Files:\n");
for (int i = 0; i < MAXHISTORY; i++) {
if (files[i] != NULL) {
printf("%d: %s\n", i + 1, files[i]);
}
}
}
int main(int argc, char *argv[]) {
char cmd[MAXLENCMD + 1] = ""; // Initialize cmd as an empty string
char history[MAXHISTORY][MAXLENCMD + 1];
char *files[MAXHISTORY];
int history_index = 0;
fprintf(stderr, "Starting VIP Shell ...\n");
// Ask for sudo password before entering VIP Shell
char sudoCmd[MAXLENCMD + 1];
snprintf(sudoCmd, sizeof(sudoCmd), "sudo -v");
if (system(sudoCmd) != 0) {
fprintf(stderr, "Failed to obtain sudo privileges.\n");
exit(1);
}
// Display ASCII art and credits only when the program is executed
printf("▒█░░▒█ ░▀░ █▀▀█ ▒█▀▀▀█ █░░█ █▀▀ █░░ █░░\n"
"░▒█▒█░ ▀█▀ █░░█ ░▀▀▀▄▄ █▀▀█ █▀▀ █░░ █░░\n"
"░░▀▄▀░ ▀▀▀ █▀▀▀ ▒█▄▄▄█ ▀░░▀ ▀▀▀ ▀▀▀ ▀▀▀\n"
"\nDeveloped by Felipe Alfonso González\n"
"Computer Science Engineer\n"
"MIT and BSD-3 Restrictive Licensed\n"
"With love from Chile ❤️\n"
"GitHub: github.com/felipealfonsog\n\n"
"Welcome to VIP Shell!\n"
"Use '--vip-help' for available options and commands.\n\n");
// Main loop for VIP Shell
while (1) {
char vip_cmd[MAXLENCMD + 1] = "";
char cwd[MAXLENCMD];
if (getcwd(cwd, sizeof(cwd)) == NULL) {
fprintf(stderr, "Error getting current working directory.\n");
exit(1);
}
print_vip_prompt(cwd);
if (fgets(vip_cmd, sizeof(vip_cmd), stdin) == NULL) {
fprintf(stderr, "Error reading command.\n");
break;
}
size_t len = strlen(vip_cmd);
if (len > 0 && vip_cmd[len - 1] == '\n') {
vip_cmd[len - 1] = '\0';
}
if (strlen(vip_cmd) == 0) {
continue;
}
// Process the command and update history
strcpy(history[history_index], vip_cmd);
files[history_index] = strdup(cwd);
history_index = (history_index + 1) % MAXHISTORY;
if (strncmp(vip_cmd, "cd ", 3) == 0) {
// Handle 'cd' command
char *new_dir = vip_cmd + 3;
if (chdir(new_dir) != 0) {
perror("chdir");
}
} else if (strcmp(vip_cmd, "exit") == 0) {
// Handle 'exit' command
printf("VIP Shell Ending.\n");
break;
} else if (strcmp(vip_cmd, "--vip-help") == 0) {
// Handle '--vip-help' command
printf("VIP Shell Options:\n"
" --vip-help Display this help message\n"
" --last-commands Display the last commands\n"
" --last-files Display the last files\n"
" exit Exit VIP Shell\n");
} else if (strcmp(vip_cmd, "--last-commands") == 0) {
// Handle '--last-commands' command
display_last_commands(history);
} else if (strcmp(vip_cmd, "--last-files") == 0) {
// Handle '--last-files' command
display_last_files(files);
} else {
// Execute other commands
execute_command(vip_cmd);
}
}
return 0;
}