-
Notifications
You must be signed in to change notification settings - Fork 0
working server/client connection and copy file #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b255472
a82ce24
b3e4ee3
7859cc2
cf1ce81
963d428
76e125e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,13 @@ | ||
| all: kilo | ||
| CC = gcc -g -Wall -W -ansi -pedantic -std=c99 -pthread -o | ||
| C+ = g++ -g -Wall -pthread -std=c++11 -o | ||
|
|
||
| all: kilo server | ||
|
|
||
| kilo: kilo.c | ||
| $(CC) -o kilo kilo.c -Wall -W -pedantic -std=c99 | ||
| $(CC) kilo kilo.c | ||
|
|
||
| server: server.cpp | ||
| $(C+) server server.cpp | ||
|
|
||
| clean: | ||
| rm kilo | ||
| rm -f kilo server transfer |
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -53,6 +53,7 @@ | |||||||||||||||||||
| #include <stdarg.h> | ||||||||||||||||||||
| #include <fcntl.h> | ||||||||||||||||||||
| #include <signal.h> | ||||||||||||||||||||
| #include <netdb.h> | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* Syntax highlight types */ | ||||||||||||||||||||
| #define HL_NORMAL 0 | ||||||||||||||||||||
|
|
@@ -109,6 +110,8 @@ struct editorConfig { | |||||||||||||||||||
| struct editorSyntax *syntax; /* Current syntax highlight, or NULL. */ | ||||||||||||||||||||
| }; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| //Note: we may want to add a few fields to the erow and editorConfig structs | ||||||||||||||||||||
|
|
||||||||||||||||||||
| static struct editorConfig E; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| enum KEY_ACTION{ | ||||||||||||||||||||
|
|
@@ -198,6 +201,7 @@ struct editorSyntax HLDB[] = { | |||||||||||||||||||
| #define HLDB_ENTRIES (sizeof(HLDB)/sizeof(HLDB[0])) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* ======================= Low level terminal handling ====================== */ | ||||||||||||||||||||
| //Note: probably don't need to edit these | ||||||||||||||||||||
|
|
||||||||||||||||||||
| static struct termios orig_termios; /* In order to restore at exit.*/ | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -214,7 +218,7 @@ void editorAtExit(void) { | |||||||||||||||||||
| disableRawMode(STDIN_FILENO); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* Raw mode: 1960 magic shit. */ | ||||||||||||||||||||
| /* Raw mode: 1960 magic*/ | ||||||||||||||||||||
| int enableRawMode(int fd) { | ||||||||||||||||||||
| struct termios raw; | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -362,6 +366,7 @@ int getWindowSize(int ifd, int ofd, int *rows, int *cols) { | |||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* ====================== Syntax highlight color scheme ==================== */ | ||||||||||||||||||||
| //Note: probably don't need to edit these | ||||||||||||||||||||
|
|
||||||||||||||||||||
| int is_separator(int c) { | ||||||||||||||||||||
| return c == '\0' || isspace(c) || strchr(",.()+-/*=~%[];",c) != NULL; | ||||||||||||||||||||
|
|
@@ -551,6 +556,10 @@ void editorSelectSyntaxHighlight(char *filename) { | |||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* ======================= Editor rows implementation ======================= */ | ||||||||||||||||||||
| //Note: probably want to edit these. perhaps at the end of an update function, we call another | ||||||||||||||||||||
| // function to send an update message to the server. | ||||||||||||||||||||
| //Note: we can copy the logic from these functions to allow for editing after receuving an | ||||||||||||||||||||
| // update message from the server. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* Update the rendered version and the syntax highlight of a row. */ | ||||||||||||||||||||
| void editorUpdateRow(erow *row) { | ||||||||||||||||||||
|
|
@@ -616,7 +625,7 @@ void editorFreeRow(erow *row) { | |||||||||||||||||||
| free(row->hl); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* Remove the row at the specified position, shifting the remainign on the | ||||||||||||||||||||
| /* Remove the row at the specified position, shifting the remaining on the | ||||||||||||||||||||
| * top. */ | ||||||||||||||||||||
| void editorDelRow(int at) { | ||||||||||||||||||||
| erow *row; | ||||||||||||||||||||
|
|
@@ -852,6 +861,7 @@ int editorSave(void) { | |||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* ============================= Terminal update ============================ */ | ||||||||||||||||||||
| //Note: probably don't need to edit these | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* We define a very simple "append buffer" structure, that is an heap | ||||||||||||||||||||
| * allocated string where we can append to. This is useful in order to | ||||||||||||||||||||
|
|
@@ -1008,6 +1018,7 @@ void editorSetStatusMessage(const char *fmt, ...) { | |||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* =============================== Find mode ================================ */ | ||||||||||||||||||||
| //Note: probably don't need to edit these | ||||||||||||||||||||
|
|
||||||||||||||||||||
| #define KILO_QUERY_LEN 256 | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -1107,6 +1118,7 @@ void editorFind(int fd) { | |||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* ========================= Editor events handling ======================== */ | ||||||||||||||||||||
| //Note: we probably don't need to edit these | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* Handle cursor position change because arrow keys were pressed. */ | ||||||||||||||||||||
| void editorMoveCursor(int key) { | ||||||||||||||||||||
|
|
@@ -1288,14 +1300,81 @@ void initEditor(void) { | |||||||||||||||||||
| signal(SIGWINCH, handleSigWinCh); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* ========================= Communication with Server ======================== */ | ||||||||||||||||||||
|
|
||||||||||||||||||||
| void receiveFile(int fd){ | ||||||||||||||||||||
| ssize_t n; | ||||||||||||||||||||
| FILE *file = fopen("transfer", "w"); | ||||||||||||||||||||
| char buffer[1024]; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| n = read(fd, buffer, 1024); | ||||||||||||||||||||
| buffer[n] = '\0'; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| while (1){ | ||||||||||||||||||||
| if ((n = read(fd, buffer, 1024)) > 0){ | ||||||||||||||||||||
| // printf("Line: %s\n", buffer); | ||||||||||||||||||||
| buffer[n] = '\0'; | ||||||||||||||||||||
| if (!strcmp(buffer, "End Transfer")){ | ||||||||||||||||||||
| // printf("Closing\n"); | ||||||||||||||||||||
| fclose(file); | ||||||||||||||||||||
| return; | ||||||||||||||||||||
| } | ||||||||||||||||||||
| fprintf(file, "%s\n", buffer); | ||||||||||||||||||||
| send(fd, "ACK", 1024, 0); //why are we sending this? | ||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 send() reads 1024 bytes from 4-byte string literal "ACK", causing buffer over-read
Suggested change
Was this helpful? React with 👍 or 👎 to provide feedback. Debug |
||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
| //editorOpen("test"); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /* ============================= Main Program ================================== */ | ||||||||||||||||||||
|
|
||||||||||||||||||||
| //main program of text-editor client | ||||||||||||||||||||
| int main(int argc, char **argv) { | ||||||||||||||||||||
| if (argc != 2) { | ||||||||||||||||||||
| fprintf(stderr,"Usage: kilo <filename>\n"); | ||||||||||||||||||||
| //check command-line args | ||||||||||||||||||||
| if (argc != 3) { | ||||||||||||||||||||
| fprintf(stderr,"Usage: kilo <host> <port>\n"); | ||||||||||||||||||||
| exit(1); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| initEditor(); | ||||||||||||||||||||
| editorSelectSyntaxHighlight(argv[1]); | ||||||||||||||||||||
| //setup | ||||||||||||||||||||
| struct addrinfo hints, *res, *traverser; | ||||||||||||||||||||
| memset(&hints, 0, sizeof(struct addrinfo)); | ||||||||||||||||||||
| hints.ai_family = AF_UNSPEC; | ||||||||||||||||||||
| hints.ai_socktype = SOCK_STREAM; | ||||||||||||||||||||
| int r = getaddrinfo(argv[1], argv[2], &hints, &res); | ||||||||||||||||||||
| if (r != 0){ | ||||||||||||||||||||
| fprintf(stderr,"Error: Can't find server.\n"); | ||||||||||||||||||||
| return 1; | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Try addresses until one is successful | ||||||||||||||||||||
| int serverFd; | ||||||||||||||||||||
| for (traverser = res; traverser; traverser = traverser->ai_next){ | ||||||||||||||||||||
| if ((serverFd = socket(traverser->ai_family, traverser->ai_socktype, traverser->ai_protocol)) != -1){ | ||||||||||||||||||||
| if ((connect(serverFd, traverser->ai_addr, traverser->ai_addrlen)) == 0){ | ||||||||||||||||||||
| break; | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
| printf("Connected\n"); | ||||||||||||||||||||
|
Comment on lines
+1358
to
+1359
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 No check for connection failure after address traversal loop After the
Suggested change
Was this helpful? React with 👍 or 👎 to provide feedback. Debug |
||||||||||||||||||||
|
|
||||||||||||||||||||
| char buffer[1024]; | ||||||||||||||||||||
| while (fgets(buffer, 1024, stdin)){ | ||||||||||||||||||||
| buffer[strcspn(buffer, "\r\n")] = 0; | ||||||||||||||||||||
| if (!strcmp(buffer, "get")){ | ||||||||||||||||||||
| printf("sending get\n"); | ||||||||||||||||||||
| send(serverFd, "get", 1024, 0); | ||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 send() reads 1024 bytes from 4-byte string literal "get", causing buffer over-read
Suggested change
Was this helpful? React with 👍 or 👎 to provide feedback. Debug |
||||||||||||||||||||
| receiveFile(serverFd); | ||||||||||||||||||||
| } | ||||||||||||||||||||
| // printf("%s\n", buffer); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| close(serverFd); | ||||||||||||||||||||
| // exit(0); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| //start editor | ||||||||||||||||||||
| initEditor(); | ||||||||||||||||||||
| editorSelectSyntaxHighlight("transfer"); | ||||||||||||||||||||
| editorOpen(argv[1]); | ||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 editorOpen(argv[1]) opens hostname instead of the transferred file "transfer"
Suggested change
Was this helpful? React with 👍 or 👎 to provide feedback. Debug |
||||||||||||||||||||
| enableRawMode(STDIN_FILENO); | ||||||||||||||||||||
| editorSetStatusMessage( | ||||||||||||||||||||
|
Comment on lines
+1375
to
1380
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚩 Editor code after fgets loop is unreachable The (Refers to lines 1375-1385) Was this helpful? React with 👍 or 👎 to provide feedback. Debug |
||||||||||||||||||||
|
|
||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,143 @@ | ||||||||||||
| // C Headers | ||||||||||||
| #include <arpa/inet.h> | ||||||||||||
| #include <errno.h> | ||||||||||||
| #include <netdb.h> | ||||||||||||
| #include <netinet/in.h> | ||||||||||||
| #include <pthread.h> | ||||||||||||
| #include <signal.h> | ||||||||||||
| #include <stdlib.h> | ||||||||||||
| #include <string.h> | ||||||||||||
| #include <sys/socket.h> | ||||||||||||
| #include <sys/types.h> | ||||||||||||
| #include <unistd.h> | ||||||||||||
| // C++ Headers | ||||||||||||
| #include <fstream> | ||||||||||||
| #include <iostream> | ||||||||||||
| #include <sstream> | ||||||||||||
| #include <map> | ||||||||||||
| #include <string> | ||||||||||||
| #include <vector> | ||||||||||||
| using namespace std; | ||||||||||||
|
|
||||||||||||
| //readFile - reads lines in file into the data structure lines | ||||||||||||
| vector<string> readFile(){ | ||||||||||||
| string line; | ||||||||||||
| vector<string> lines; | ||||||||||||
| ifstream file("test"); | ||||||||||||
| while (getline(file, line)){ | ||||||||||||
| lines.push_back(line); | ||||||||||||
| } | ||||||||||||
| return lines; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| //sendFile - send file line-by-line to a client at fd | ||||||||||||
| void sendFile(int fd, vector<string> lines){ | ||||||||||||
| vector<string>::iterator i; | ||||||||||||
|
|
||||||||||||
| send(fd, (void*)"Start Transfer", 1024, 0); | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 send() reads 1024 bytes from 15-byte "Start Transfer" literal
Suggested change
Was this helpful? React with 👍 or 👎 to provide feedback. Debug |
||||||||||||
|
|
||||||||||||
| /* for (i = lines.begin(); i != lines.end(); i++){ | ||||||||||||
| char buffer[1024]; | ||||||||||||
| string msg = *i; | ||||||||||||
| // cout << "Line: " << msg << endl; | ||||||||||||
| send(fd, msg.c_str(), msg.length(), 0); | ||||||||||||
| read(fd, buffer, 1024); | ||||||||||||
| } */ | ||||||||||||
|
|
||||||||||||
| //this is the same as the loop that is commented out | ||||||||||||
| for(string msg : lines){ | ||||||||||||
| char buffer[1024]; | ||||||||||||
|
|
||||||||||||
| send(fd, msg.c_str(), msg.length(), 0); | ||||||||||||
| read(fd, buffer, 1024); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| send(fd, (void*)"End Transfer", 1024, 0); | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 send() reads 1024 bytes from 13-byte "End Transfer" literal
Suggested change
Was this helpful? React with 👍 or 👎 to provide feedback. Debug |
||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| //threadFunc - thread function to read any messages from a client | ||||||||||||
| void *threadFunc(void *args){ | ||||||||||||
| ssize_t n; | ||||||||||||
| int clientFd = *(int*)args; | ||||||||||||
| char buffer[1024]; | ||||||||||||
| pthread_detach(pthread_self()); | ||||||||||||
|
|
||||||||||||
| // Read until disconnection | ||||||||||||
| while ((n = read(clientFd, buffer, 1024)) > 0){ | ||||||||||||
| string line(buffer); | ||||||||||||
|
Comment on lines
+66
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Buffer from read() not null-terminated before constructing std::string At
Suggested change
Was this helpful? React with 👍 or 👎 to provide feedback. Debug |
||||||||||||
|
|
||||||||||||
| if (line == "exit"){ | ||||||||||||
| close(clientFd); | ||||||||||||
| } | ||||||||||||
| else if (line == "get"){ | ||||||||||||
| cout << "Get Received" << endl; | ||||||||||||
| sendFile(clientFd, readFile()); | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| return NULL; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| //handleSigInt - action performed when user types ctrl-C | ||||||||||||
| void handleSigInt(int unused __attribute__((unused))){ | ||||||||||||
| exit(0); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| //main server program | ||||||||||||
| int main(void){ | ||||||||||||
|
|
||||||||||||
| //setup SIGINT signal handler | ||||||||||||
| signal(SIGINT, handleSigInt); | ||||||||||||
|
|
||||||||||||
| // Create server socket | ||||||||||||
| int serverFd; | ||||||||||||
| if ((serverFd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ | ||||||||||||
| std::cerr << "Error: Can't create socket." << std::endl; | ||||||||||||
| return 1; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // Set options for socket | ||||||||||||
| int val; | ||||||||||||
| if (setsockopt(serverFd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int))){ | ||||||||||||
|
Comment on lines
+99
to
+100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 setsockopt(SO_REUSEADDR) uses uninitialized val variable
Suggested change
Was this helpful? React with 👍 or 👎 to provide feedback. Debug |
||||||||||||
| std::cerr << "Error: Can't reuse socket." << std::endl; | ||||||||||||
| return 2; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // Configure addr and bind | ||||||||||||
| struct sockaddr_in serverAddr; | ||||||||||||
| serverAddr.sin_family = AF_INET; | ||||||||||||
| serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); | ||||||||||||
| serverAddr.sin_port = htons(10001); | ||||||||||||
| if (bind(serverFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1){ | ||||||||||||
| cerr << "Error: Can't bind socket to port." << endl; | ||||||||||||
| return 3; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // Listen for client connections | ||||||||||||
| if (listen(serverFd, 20) < 0){ | ||||||||||||
| cerr << "Error: Can't listen for clients." << endl; | ||||||||||||
| return 4; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // Get name and port assigned to server | ||||||||||||
| char *name = new char[1024]; | ||||||||||||
| struct sockaddr_in infoAddr; | ||||||||||||
| socklen_t len = sizeof(infoAddr); | ||||||||||||
| gethostname(name, 1024); | ||||||||||||
| getsockname(serverFd, (struct sockaddr *)&infoAddr, &len); | ||||||||||||
|
|
||||||||||||
| // Report name and port | ||||||||||||
| cout << name << ":" << ntohs(serverAddr.sin_port)<< endl; | ||||||||||||
| delete name; | ||||||||||||
|
|
||||||||||||
| // Connect a client | ||||||||||||
| struct sockaddr_in cliAddr; | ||||||||||||
| len = sizeof(cliAddr); | ||||||||||||
| while (true){ | ||||||||||||
| int clientFd = accept(serverFd, (struct sockaddr *)&serverAddr, &len); | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 accept() writes client address into serverAddr, corrupting server's own address
Suggested change
Was this helpful? React with 👍 or 👎 to provide feedback. Debug |
||||||||||||
|
|
||||||||||||
| // Create thread to deal with client | ||||||||||||
| pthread_t thread; | ||||||||||||
| pthread_create(&thread, NULL, threadFunc, (void *)&clientFd); | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Race condition: pointer to loop-local clientFd passed to thread
Prompt for agentsWas this helpful? React with 👍 or 👎 to provide feedback. Debug |
||||||||||||
| } | ||||||||||||
| return 0; | ||||||||||||
| } | ||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| this is a test file | ||
| these are some words | ||
| these are some more | ||
| bye! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 receiveFile() uses read() return value as index without checking for error (-1)
At
kilo.c:1310-1311,n = read(fd, buffer, 1024)may return -1 on error, but the code immediately doesbuffer[n] = '\0'without checking. Whenn == -1, this writes tobuffer[-1], an out-of-bounds memory write.Was this helpful? React with 👍 or 👎 to provide feedback.
Debug
Playground