Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
Cs283
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Joey Le
Cs283
Commits
4143e2cd
Commit
4143e2cd
authored
3 months ago
by
Joey Le
Browse files
Options
Downloads
Patches
Plain Diff
Fixed a bunch of the functions. Hopefully it works now
parent
52c21eea
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
Assignment-06/starter/dshlib.c
+56
-70
56 additions, 70 deletions
Assignment-06/starter/dshlib.c
Assignment-06/starter/rsh_cli.c
+59
-19
59 additions, 19 deletions
Assignment-06/starter/rsh_cli.c
Assignment-06/starter/rsh_server.c
+90
-63
90 additions, 63 deletions
Assignment-06/starter/rsh_server.c
with
205 additions
and
152 deletions
Assignment-06/starter/dshlib.c
+
56
−
70
View file @
4143e2cd
...
@@ -263,58 +263,40 @@ static void start_server() {
...
@@ -263,58 +263,40 @@ static void start_server() {
* fork(), execvp(), exit(), chdir()
* fork(), execvp(), exit(), chdir()
*/
*/
int
exec_remote_cmd_loop
(
char
*
address
,
int
port
)
{
char
cmd_buff
[
RDSH_COMM_BUFF_SZ
];
char
rsp_buff
[
RDSH_COMM_BUFF_SZ
];
int
cli_socket
;
ssize_t
recv_bytes
;
int
is_eof
;
// Connect to the server
int
exec_local_cmd_loop
()
{
cli_socket
=
start_client
(
address
,
port
);
char
cmd_buff
[
SH_CMD_MAX
];
if
(
cli_socket
<
0
)
{
int
rc
=
OK
;
perror
(
"start client"
);
return
client_cleanup
(
cli_socket
,
NULL
,
NULL
,
ERR_RDSH_CLIENT
);
while
(
1
)
{
printf
(
"%s"
,
SH_PROMPT
);
if
(
fgets
(
cmd_buff
,
SH_CMD_MAX
,
stdin
)
==
NULL
)
{
printf
(
"
\n
"
);
break
;
}
}
cmd_buff
[
strcspn
(
cmd_buff
,
"
\n
"
)]
=
'\0'
;
while
(
1
)
{
printf
(
"rsh> "
);
if
(
strlen
(
cmd_buff
)
==
0
)
{
if
(
!
fgets
(
cmd_buff
,
RDSH_COMM_BUFF_SZ
,
stdin
))
{
printf
(
"%s
\n
"
,
CMD_WARN_NO_CMD
);
break
;
// Exit on input error or EOF
rc
=
WARN_NO_CMDS
;
continue
;
}
}
if
(
strstr
(
cmd_buff
,
"|"
)
!=
NULL
)
{
// Remove the newline character from the command
command_list_t
cmd_list
;
size_t
cmd_len
=
strlen
(
cmd_buff
);
if
(
parse_pipeline
(
cmd_buff
,
&
cmd_list
)
!=
OK
)
{
if
(
cmd_len
>
0
&&
cmd_buff
[
cmd_len
-
1
]
==
'\n'
)
{
fprintf
(
stderr
,
"%s
\n
"
,
CMD_ERR_PIPE_LIMIT
);
cmd_buff
[
cmd_len
-
1
]
=
'\0'
;
rc
=
ERR_TOO_MANY_COMMANDS
;
continue
;
}
}
// Execute the pipeline
// Handle local commands (e.g., cd, exit)
if
(
strncmp
(
cmd_buff
,
"cd"
,
2
)
==
0
)
{
execute_pipeline
(
&
cmd_list
);
// Handle cd locally
// Free memory for each command's buffer
for
(
int
i
=
0
;
i
<
cmd_list
.
num
;
i
++
)
{
free
(
cmd_list
.
commands
[
i
].
_cmd_buffer
);
}
}
else
{
cmd_buff_t
cmd
;
cmd_buff_t
cmd
;
if
(
build_cmd_buff
(
cmd_buff
,
&
cmd
)
!=
OK
)
{
if
(
build_cmd_buff
(
cmd_buff
,
&
cmd
)
!=
OK
)
{
fprintf
(
stderr
,
"%s
\n
"
,
CMD_ERR_PIPE_LIMIT
);
fprintf
(
stderr
,
"%s
\n
"
,
CMD_ERR_PIPE_LIMIT
);
rc
=
ERR_MEMORY
;
continue
;
continue
;
}
}
if
(
strcmp
(
cmd
.
argv
[
0
],
EXIT_CMD
)
==
0
)
{
free
(
cmd
.
_cmd_buffer
);
break
;
}
if
(
strcmp
(
cmd
.
argv
[
0
],
"cd"
)
==
0
)
{
if
(
cmd
.
argc
==
1
)
{
if
(
cmd
.
argc
==
1
)
{
chdir
(
getenv
(
"HOME"
));
chdir
(
getenv
(
"HOME"
));
}
else
if
(
cmd
.
argc
==
2
)
{
}
else
if
(
cmd
.
argc
==
2
)
{
...
@@ -326,31 +308,35 @@ int exec_local_cmd_loop() {
...
@@ -326,31 +308,35 @@ int exec_local_cmd_loop() {
}
}
free
(
cmd
.
_cmd_buffer
);
free
(
cmd
.
_cmd_buffer
);
continue
;
continue
;
}
else
if
(
strncmp
(
cmd_buff
,
"exit"
,
4
)
==
0
)
{
break
;
// Exit the remote shell
}
}
pid_t
pid
=
fork
();
// Send the command to the server
if
(
pid
<
0
)
{
ssize_t
sent_bytes
=
send
(
cli_socket
,
cmd_buff
,
strlen
(
cmd_buff
),
0
);
perror
(
"fork failed"
);
if
(
sent_bytes
<
0
)
{
rc
=
ERR_MEMORY
;
perror
(
"send"
);
}
else
if
(
pid
==
0
)
{
return
client_cleanup
(
cli_socket
,
NULL
,
NULL
,
ERR_RDSH_COMMUNICATION
);
execvp
(
cmd
.
argv
[
0
],
cmd
.
argv
);
perror
(
"execvp failed"
);
exit
(
EXIT_FAILURE
);
}
else
{
int
status
;
wait
(
&
status
);
if
(
WIFEXITED
(
status
))
{
if
(
WEXITSTATUS
(
status
)
!=
0
)
{
fprintf
(
stderr
,
"Command failed with exit code %d
\n
"
,
WEXITSTATUS
(
status
));
}
}
// Receive the server's response
is_eof
=
0
;
while
((
recv_bytes
=
recv
(
cli_socket
,
rsp_buff
,
RDSH_COMM_BUFF_SZ
,
0
))
>
0
)
{
printf
(
"%.*s"
,
(
int
)
recv_bytes
,
rsp_buff
);
if
(
rsp_buff
[
recv_bytes
-
1
]
==
RDSH_EOF_CHAR
)
{
is_eof
=
1
;
break
;
}
}
}
}
free
(
cmd
.
_cmd_buffer
);
if
(
recv_bytes
<
0
)
{
perror
(
"recv"
);
return
client_cleanup
(
cli_socket
,
NULL
,
NULL
,
ERR_RDSH_COMMUNICATION
);
}
else
if
(
recv_bytes
==
0
)
{
printf
(
"Server closed the connection
\n
"
);
break
;
}
}
}
}
return
r
c
;
return
c
lient_cleanup
(
cli_socket
,
NULL
,
NULL
,
OK
)
;
}
}
This diff is collapsed.
Click to expand it.
Assignment-06/starter/rsh_cli.c
+
59
−
19
View file @
4143e2cd
...
@@ -92,32 +92,49 @@
...
@@ -92,32 +92,49 @@
*/
*/
int
exec_remote_cmd_loop
(
char
*
address
,
int
port
)
int
exec_remote_cmd_loop
(
char
*
address
,
int
port
)
{
{
char
*
cmd_buff
;
char
cmd_buff
[
RDSH_COMM_BUFF_SZ
];
// Use the buffer size from rshlib.h
char
*
rsp_buff
;
char
rsp_buff
[
RDSH_COMM_BUFF_SZ
]
;
int
cli_socket
;
int
cli_socket
;
ssize_t
io_size
;
ssize_t
recv_bytes
;
int
is_eof
;
int
is_eof
;
// TODO set up cmd and response buffs
// Connect to the server
cli_socket
=
start_client
(
address
,
port
);
cli_socket
=
start_client
(
address
,
port
);
if
(
cli_socket
<
0
)
{
if
(
cli_socket
<
0
)
{
perror
(
"start client"
);
perror
(
"start client"
);
return
client_cleanup
(
cli_socket
,
cmd_buff
,
rsp_buff
,
ERR_RDSH_CLIENT
);
return
client_cleanup
(
cli_socket
,
NULL
,
NULL
,
ERR_RDSH_CLIENT
);
}
}
while
(
1
)
while
(
1
)
{
{
printf
(
"rsh> "
);
// TODO print prompt
if
(
!
fgets
(
cmd_buff
,
RDSH_COMM_BUFF_SZ
,
stdin
))
{
break
;
}
// TODO fgets input
if
(
send
(
cli_socket
,
cmd_buff
,
strlen
(
cmd_buff
),
0
)
<
0
)
{
perror
(
"send"
);
return
client_cleanup
(
cli_socket
,
NULL
,
NULL
,
ERR_RDSH_COMMUNICATION
);
}
// TODO send() over cli_socket
is_eof
=
0
;
while
((
recv_bytes
=
recv
(
cli_socket
,
rsp_buff
,
RDSH_COMM_BUFF_SZ
,
0
))
>
0
)
{
printf
(
"%.*s"
,
(
int
)
recv_bytes
,
rsp_buff
);
// Print the received data
if
(
rsp_buff
[
recv_bytes
-
1
]
==
RDSH_EOF_CHAR
)
{
is_eof
=
1
;
// Check for EOF character
break
;
}
}
// TODO recv all the results
if
(
recv_bytes
<
0
)
{
perror
(
"recv"
);
return
client_cleanup
(
cli_socket
,
NULL
,
NULL
,
ERR_RDSH_COMMUNICATION
);
}
// TODO break on exit command
if
(
strncmp
(
cmd_buff
,
"exit"
,
4
)
==
0
||
strncmp
(
cmd_buff
,
"stop-server"
,
11
)
==
0
)
{
break
;
}
}
}
return
client_cleanup
(
cli_socket
,
cmd_buff
,
rsp_buff
,
OK
);
return
client_cleanup
(
cli_socket
,
cmd_buff
,
rsp_buff
,
OK
);
}
}
...
@@ -151,6 +168,29 @@ int start_client(char *server_ip, int port){
...
@@ -151,6 +168,29 @@ int start_client(char *server_ip, int port){
int
ret
;
int
ret
;
// TODO set up cli_socket
// TODO set up cli_socket
cli_socket
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
cli_socket
<
0
)
{
perror
(
"socket"
);
return
ERR_RDSH_CLIENT
;
}
// Set up the server address structure
memset
(
&
addr
,
0
,
sizeof
(
addr
));
addr
.
sin_family
=
AF_INET
;
addr
.
sin_port
=
htons
(
port
);
if
(
inet_pton
(
AF_INET
,
server_ip
,
&
addr
.
sin_addr
)
<=
0
)
{
perror
(
"inet_pton"
);
close
(
cli_socket
);
return
ERR_RDSH_CLIENT
;
}
// Connect to the server
ret
=
connect
(
cli_socket
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
));
if
(
ret
<
0
)
{
perror
(
"connect"
);
close
(
cli_socket
);
return
ERR_RDSH_CLIENT
;
}
return
cli_socket
;
return
cli_socket
;
...
...
This diff is collapsed.
Click to expand it.
Assignment-06/starter/rsh_server.c
+
90
−
63
View file @
4143e2cd
...
@@ -302,73 +302,109 @@ int boot_server(char *ifaces, int port){
...
@@ -302,73 +302,109 @@ int boot_server(char *ifaces, int port){
*/
*/
int
exec_client_requests
(
int
cli_socket
)
{
int
exec_client_requests
(
int
cli_socket
)
{
char
*
io_buff
;
char
cmd_buff
[
RDSH_COMM_BUFF_SZ
];
int
io_size
;
ssize_t
recv_bytes
;
command_list_t
cmd_list
;
int
rc
=
OK
;
int
rc
=
OK
;
// Allocate a buffer for I/O operations
io_buff
=
malloc
(
RDSH_COMM_BUFF_SZ
);
if
(
io_buff
==
NULL
)
{
return
ERR_RDSH_SERVER
;
// Return server error if allocation fails
}
while
(
1
)
{
while
(
1
)
{
// Receive input from the client
recv_bytes
=
recv
(
cli_socket
,
cmd_buff
,
RDSH_COMM_BUFF_SZ
,
0
);
io_size
=
recv
(
cli_socket
,
io_buff
,
RDSH_COMM_BUFF_SZ
,
0
);
if
(
recv_bytes
<=
0
)
{
if
(
io_size
<
0
)
{
close
(
cli_socket
);
perror
(
"recv"
);
printf
(
"Client disconnected
\n
"
);
free
(
io_buff
);
return
OK
;
return
ERR_RDSH_COMMUNICATION
;
// Return communication error
}
else
if
(
io_size
==
0
)
{
// Client disconnected
free
(
io_buff
);
return
OK
;
// Return OK to accept another client
}
}
// Null-terminate the received data
cmd_buff
[
recv_bytes
]
=
'\0'
;
io_buff
[
io_size
]
=
'\0'
;
// Check for special commands
cmd_buff
[
strcspn
(
cmd_buff
,
"
\n
"
)]
=
'\0'
;
if
(
strncmp
(
io_buff
,
"exit"
,
strlen
(
"exit"
))
==
0
)
{
// Client sent the `exit` command
if
(
strlen
(
cmd_buff
)
==
0
)
{
free
(
io_buff
);
send_message_string
(
cli_socket
,
CMD_WARN_NO_CMD
);
return
OK
;
// Return OK to accept another client
}
else
if
(
strncmp
(
io_buff
,
"stop-server"
,
strlen
(
"stop-server"
))
==
0
)
{
// Client sent the `stop-server` command
free
(
io_buff
);
return
OK_EXIT
;
// Return OK_EXIT to stop the server
}
// Parse the input into a command list
rc
=
parse_pipeline
(
io_buff
,
&
cmd_list
);
if
(
rc
!=
OK
)
{
// Handle parsing error
send_message_string
(
cli_socket
,
CMD_ERR_RDSH_EXEC
);
send_message_eof
(
cli_socket
);
send_message_eof
(
cli_socket
);
continue
;
// Continue to the next iteration
rc
=
WARN_NO_CMDS
;
continue
;
}
}
// Execute the command pipeline
if
(
strstr
(
cmd_buff
,
"|"
)
!=
NULL
)
{
rc
=
rsh_execute_pipeline
(
cli_socket
,
&
cmd_list
);
command_list_t
cmd_list
;
if
(
rc
<
0
)
{
if
(
parse_pipeline
(
cmd_buff
,
&
cmd_list
)
!=
OK
)
{
// Handle execution error
send_message_string
(
cli_socket
,
CMD_ERR_PIPE_LIMIT
);
send_message_string
(
cli_socket
,
CMD_ERR_RDSH_EXEC
);
send_message_eof
(
cli_socket
);
send_message_eof
(
cli_socket
);
continue
;
// Continue to the next iteration
rc
=
ERR_TOO_MANY_COMMANDS
;
continue
;
}
}
// Free memory for each command's buffer
rc
=
rsh_execute_pipeline
(
cli_socket
,
&
cmd_list
);
for
(
int
i
=
0
;
i
<
cmd_list
.
num
;
i
++
)
{
for
(
int
i
=
0
;
i
<
cmd_list
.
num
;
i
++
)
{
free
(
cmd_list
.
commands
[
i
].
_cmd_buffer
);
free
(
cmd_list
.
commands
[
i
].
_cmd_buffer
);
}
}
}
else
{
cmd_buff_t
cmd
;
if
(
build_cmd_buff
(
cmd_buff
,
&
cmd
)
!=
OK
)
{
send_message_string
(
cli_socket
,
CMD_ERR_PIPE_LIMIT
);
send_message_eof
(
cli_socket
);
rc
=
ERR_MEMORY
;
continue
;
}
if
(
strcmp
(
cmd
.
argv
[
0
],
EXIT_CMD
)
==
0
)
{
free
(
cmd
.
_cmd_buffer
);
send_message_string
(
cli_socket
,
"Exiting...
\n
"
);
send_message_eof
(
cli_socket
);
return
OK
;
}
else
if
(
strcmp
(
cmd
.
argv
[
0
],
"stop-server"
)
==
0
)
{
free
(
cmd
.
_cmd_buffer
);
send_message_string
(
cli_socket
,
"Stopping server...
\n
"
);
send_message_eof
(
cli_socket
);
return
OK_EXIT
;
}
else
if
(
strcmp
(
cmd
.
argv
[
0
],
"cd"
)
==
0
)
{
if
(
cmd
.
argc
==
1
)
{
chdir
(
getenv
(
"HOME"
));
}
else
if
(
cmd
.
argc
==
2
)
{
if
(
chdir
(
cmd
.
argv
[
1
])
!=
0
)
{
char
error_msg
[
256
];
snprintf
(
error_msg
,
sizeof
(
error_msg
),
"cd: %s
\n
"
,
strerror
(
errno
));
send_message_string
(
cli_socket
,
error_msg
);
}
}
else
{
send_message_string
(
cli_socket
,
CMD_ERR_PIPE_LIMIT
);
}
send_message_eof
(
cli_socket
);
free
(
cmd
.
_cmd_buffer
);
continue
;
}
pid_t
pid
=
fork
();
if
(
pid
<
0
)
{
perror
(
"fork failed"
);
rc
=
ERR_MEMORY
;
}
else
if
(
pid
==
0
)
{
execvp
(
cmd
.
argv
[
0
],
cmd
.
argv
);
perror
(
"execvp failed"
);
exit
(
EXIT_FAILURE
);
}
else
{
int
status
;
wait
(
&
status
);
if
(
WIFEXITED
(
status
))
{
if
(
WEXITSTATUS
(
status
)
!=
0
)
{
char
error_msg
[
256
];
snprintf
(
error_msg
,
sizeof
(
error_msg
),
"Command failed with exit code %d
\n
"
,
WEXITSTATUS
(
status
));
send_message_string
(
cli_socket
,
error_msg
);
}
}
}
free
(
cmd
.
_cmd_buffer
);
}
send_message_eof
(
cli_socket
);
}
}
// Clean up (this will never be reached due to the while(1) loop)
return
rc
;
free
(
io_buff
);
return
WARN_RDSH_NOT_IMPL
;
// Default return value
}
}
/*
/*
* send_message_eof(cli_socket)
* send_message_eof(cli_socket)
* cli_socket: The server-side socket that is connected to the client
* cli_socket: The server-side socket that is connected to the client
...
@@ -384,25 +420,16 @@ int exec_client_requests(int cli_socket) {
...
@@ -384,25 +420,16 @@ int exec_client_requests(int cli_socket) {
* we were unable to send the EOF character.
* we were unable to send the EOF character.
*/
*/
int
send_message_string
(
int
cli_socket
,
char
*
buff
)
{
int
send_message_eof
(
int
cli_socket
)
{
int
bytes_sent
;
if
(
send
(
cli_socket
,
&
RDSH_EOF_CHAR
,
1
,
0
)
<
0
)
{
// Send the message
bytes_sent
=
send
(
cli_socket
,
buff
,
strlen
(
buff
),
0
);
if
(
bytes_sent
<
0
)
{
perror
(
"send"
);
perror
(
"send"
);
return
ERR_RDSH_COMMUNICATION
;
return
ERR_RDSH_COMMUNICATION
;
}
}
// Send the EOF character
if
(
send_message_eof
(
cli_socket
)
!=
OK
)
{
return
ERR_RDSH_COMMUNICATION
;
}
return
OK
;
return
OK
;
}
}
/*
/*
* send_message_string(cli_socket, char *buff)
* send_message_string(cli_socket, char *buff)
* cli_socket: The server-side socket that is connected to the client
* cli_socket: The server-side socket that is connected to the client
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment