moving from gitlab
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
float temp;
|
||||
char unit;
|
||||
|
||||
printf("Enter temp and unit (25.0 C) ");
|
||||
|
||||
scanf("%f %c", &temp, &unit);
|
||||
if (unit == 'C' || unit == 'c') {
|
||||
printf("%.2fC is ", temp);
|
||||
temp = temp * (9.0 / 5.0) + 32.0;
|
||||
printf("%.2fF\n", temp);
|
||||
} else if (unit == 'F' || unit == 'f') {
|
||||
printf("%.2fF is ", temp);
|
||||
temp = (temp - 32.0) * 5.0 / 9.0;
|
||||
printf("%.2fC\n", temp);
|
||||
} else {
|
||||
printf("Unknown temperature unit. Use C or F\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <stdio.h> // output to terminal
|
||||
#include <stdlib.h> // has our atoi method
|
||||
|
||||
long factorial(int n);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
// get first to arguments passed
|
||||
// very first is name of program
|
||||
printf("argv[0]: %s\n", argv[0]);
|
||||
// argv[0] = ./nameofexecutable
|
||||
// argv[1] will be our value to caluclate factorial
|
||||
|
||||
if (argc < 2) {
|
||||
printf("error: value to calculate factorial is missing");
|
||||
printf("\tUsage: ./factorial 3\n\twhere 3 is the value to calculate\n");
|
||||
return -1;
|
||||
}
|
||||
// convert our char * to an int
|
||||
int n = atoi(argv[1]);
|
||||
|
||||
printf("Factorial of %d is %ld\n", n, factorial(n));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// use recursion first time through?
|
||||
// then maybe show a simple for loop
|
||||
long factorial(int n) {
|
||||
|
||||
// factorial is annotated as N!
|
||||
// example: 5! = 5 x 4 x 3 x 2 x 1
|
||||
// 0! = 1
|
||||
// so properties of math yada yada..
|
||||
// we can: 5! = 1 x 2 x 3 x 4 x 5
|
||||
// we can use a basic loop and go all the way up to n
|
||||
long answer = 1;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
// answer = answer * i;
|
||||
answer *= i;
|
||||
}
|
||||
return answer;
|
||||
|
||||
if (n == 1)
|
||||
return 1;
|
||||
return n * factorial(n - 1);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <stdio.h>
|
||||
|
||||
FILE *openFile(const char *filename);
|
||||
void catFile(FILE *file);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
if (argc != 2) {
|
||||
printf("error: missing file\nusage: cat <filename>\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
FILE *file = openFile(argv[1]);
|
||||
if (!file) {
|
||||
printf("error: file (%s) not found\n", argv[1]);
|
||||
return -2;
|
||||
}
|
||||
|
||||
catFile(file);
|
||||
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *openFile(const char *filename) {
|
||||
FILE *file;
|
||||
|
||||
file = fopen(filename, "r");
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
void catFile(FILE *file) {
|
||||
char buf[512];
|
||||
while (fgets(buf, 512, file)) {
|
||||
printf("%s", buf);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
[Verse 1]
|
||||
We're no strangers to love
|
||||
You know the rules and so do I (Do I)
|
||||
A full commitment's what I'm thinking of
|
||||
You wouldn't get this from any other guy
|
||||
|
||||
[Pre-Chorus]
|
||||
I just wanna tell you how I'm feeling
|
||||
Gotta make you understand
|
||||
|
||||
[Chorus]
|
||||
Never gonna give you up
|
||||
Never gonna let you down
|
||||
Never gonna run around and desert you
|
||||
Never gonna make you cry
|
||||
Never gonna say goodbye
|
||||
Never gonna tell a lie and hurt you
|
||||
|
||||
[Verse 2]
|
||||
We've known each other for so long
|
||||
Your heart's been aching, but you're too shy to say it (To say it)
|
||||
Inside, we both know what's been going on (Going on)
|
||||
We know the game, and we're gonna play it
|
||||
|
||||
[Pre-Chorus]
|
||||
And if you ask me how I'm feeling
|
||||
Don't tell me you're too blind to see
|
||||
|
||||
[Chorus]
|
||||
Never gonna give you up
|
||||
Never gonna let you down
|
||||
Never gonna run around and desert you
|
||||
Never gonna make you cry
|
||||
Never gonna say goodbye
|
||||
Never gonna tell a lie and hurt you
|
||||
Never gonna give you up
|
||||
Never gonna let you down
|
||||
Never gonna run around and desert you
|
||||
Never gonna make you cry
|
||||
Never gonna say goodbye
|
||||
Never gonna tell a lie and hurt you
|
||||
|
||||
+1000
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
unsigned int getSum(FILE *file);
|
||||
char getFirstDigit(const char *line, size_t len);
|
||||
char getLastDigit(const char *line, size_t len);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
if (argc != 2) {
|
||||
printf("error: missing file input\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *file = fopen(argv[1], "r");
|
||||
if (file == NULL) {
|
||||
printf("could not open file: %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int sum = getSum(file);
|
||||
printf("%d\n", sum);
|
||||
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int getSum(FILE *file) {
|
||||
|
||||
unsigned int sum = 0;
|
||||
size_t len = 0;
|
||||
size_t read;
|
||||
char *line = NULL;
|
||||
|
||||
while ((read = getline(&line, &len, file)) != -1) {
|
||||
printf("%s", line);
|
||||
char first = getFirstDigit(line, read);
|
||||
char last = getLastDigit(line, read);
|
||||
printf("%c%c\n", first, last);
|
||||
char digits[3] = {first, last, '\0'};
|
||||
sum += atoi(digits);
|
||||
}
|
||||
|
||||
free(line);
|
||||
return sum;
|
||||
}
|
||||
|
||||
char getFirstDigit(const char *line, size_t len) {
|
||||
|
||||
char digit;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (isdigit(line[i])) {
|
||||
digit = (char)line[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return digit;
|
||||
}
|
||||
|
||||
char getLastDigit(const char *line, size_t len) {
|
||||
|
||||
char digit;
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
if (isdigit(line[i])) {
|
||||
digit = (char)line[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return digit;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
1abc2
|
||||
pqr3stu8vwx
|
||||
a1b2c3d4e5f
|
||||
treb7uchet
|
||||
@@ -0,0 +1,73 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct time {
|
||||
unsigned int hours, minutes, seconds;
|
||||
};
|
||||
|
||||
unsigned int timeToSeconds(struct time);
|
||||
struct time secondsToTime(unsigned int);
|
||||
void displayTime(unsigned int);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
struct time t;
|
||||
t.seconds = 0;
|
||||
t.minutes = 0;
|
||||
t.hours = 0;
|
||||
char c;
|
||||
|
||||
if (argc == 1) {
|
||||
printf("No time passed--using default: 1 min\n");
|
||||
t.minutes = 1;
|
||||
} else {
|
||||
while ((c = getopt(argc, argv, "h:m:s:")) != -1) {
|
||||
switch (c) {
|
||||
case 'h':
|
||||
t.hours = atoi(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
t.minutes = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
t.seconds = atoi(optarg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int seconds = timeToSeconds(t);
|
||||
while (seconds > 0) {
|
||||
|
||||
displayTime(seconds);
|
||||
sleep(1);
|
||||
seconds -= 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int timeToSeconds(struct time t) {
|
||||
unsigned int seconds = 0;
|
||||
|
||||
seconds = t.seconds;
|
||||
seconds += t.minutes * 60;
|
||||
seconds += t.hours * 60 * 60;
|
||||
return seconds;
|
||||
}
|
||||
struct time secondsToTime(unsigned int seconds) {
|
||||
struct time t;
|
||||
|
||||
t.hours = seconds / 3600;
|
||||
t.minutes = (seconds - (3600 * t.hours)) / 60;
|
||||
t.seconds = (seconds - (3600 * t.hours)) - (t.minutes * 60);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void displayTime(unsigned int seconds) {
|
||||
system("clear");
|
||||
struct time t = secondsToTime(seconds);
|
||||
printf("%02d:%02d:%02d\n", t.hours, t.minutes, t.seconds);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void findreplace(char *str, const char *oldword, const char *newword);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
// ./a.out filename oldWord newWord
|
||||
if (argc != 4) {
|
||||
printf("usage: %s filename oldword newword\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *filename = argv[1];
|
||||
char *oldWord = argv[2];
|
||||
char *newWord = argv[3];
|
||||
|
||||
if (!strcmp(oldWord, newWord)) {
|
||||
printf("error: words are the same\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *file = fopen(filename, "r");
|
||||
FILE *tmpf = fopen("tmp.txt", "w");
|
||||
if (!file || !tmpf) {
|
||||
printf("could not open files\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t size = 256;
|
||||
char buf[size];
|
||||
// loop
|
||||
while ((fgets(buf, size, file)) != NULL) {
|
||||
//printf("%s", buf);
|
||||
findreplace(buf, oldWord, newWord);
|
||||
|
||||
fputs(buf, tmpf);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
fclose(tmpf);
|
||||
|
||||
remove(filename);
|
||||
rename("tmp.txt", filename);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void findreplace(char *str, const char *oldword, const char *newword) {
|
||||
char *pos, tmp[256];
|
||||
int index = 0;
|
||||
int oldLen = strlen(oldword);
|
||||
while ((pos = strstr(str, oldword)) != NULL) {
|
||||
strcpy(tmp, str);
|
||||
index = pos - str;
|
||||
str[index] = '\0';
|
||||
strcat(str, newword);
|
||||
strcat(str, tmp + index + oldLen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
Hello Thing
|
||||
This is a text file about the Thing
|
||||
This is my world
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
//
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
return 0;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
create table Todos (
|
||||
Id integer PRIMARY KEY NOT NULL,
|
||||
Title varchar(128) NOT NULL,
|
||||
Completed integer NOT NULL
|
||||
);
|
||||
|
||||
insert into Todos values(NULL, 'code this app', 0);
|
||||
insert into Todos values(NULL, 'finish this video', 0);
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
#include <sqlite3.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
enum ERR { OK, ERROR };
|
||||
|
||||
sqlite3 *setupDB();
|
||||
enum ERR addTodo(sqlite3 *db);
|
||||
enum ERR markComplete(sqlite3 *db);
|
||||
enum ERR deleteTodo(sqlite3 *db);
|
||||
enum ERR updateTodo(sqlite3 *db);
|
||||
enum ERR listAll(sqlite3 *db);
|
||||
int numberTodos(sqlite3 *db);
|
||||
int completedTodos(sqlite3 *db);
|
||||
|
||||
void menu(sqlite3 *db);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
sqlite3 *db = setupDB();
|
||||
if (!db) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
menu(db);
|
||||
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sqlite3 *setupDB() {
|
||||
sqlite3 *db;
|
||||
int rc = sqlite3_open("todo.db", &db);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Cannot open database %s\n", sqlite3_errmsg(db));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
void menu(sqlite3 *db) {
|
||||
|
||||
printf("------------------------\n");
|
||||
printf("T E R M I N A L T O D O\n\n");
|
||||
|
||||
char input;
|
||||
int count, done;
|
||||
while (1) {
|
||||
if ((count = numberTodos(db)) == -1)
|
||||
return;
|
||||
if ((done = completedTodos(db)) == -1)
|
||||
return;
|
||||
printf("You currently have %d Todos.\n", count);
|
||||
printf("You have completed %d Todos!\n\n", done);
|
||||
|
||||
printf("What would you like todo?\n");
|
||||
printf("[A]dd, [L]ist, [C]omplete, [U]pdate, [R]emove, [Q]uit\n");
|
||||
printf("> ");
|
||||
input = getchar();
|
||||
while (getchar() != '\n')
|
||||
;
|
||||
printf("\n");
|
||||
|
||||
enum ERR err;
|
||||
switch (input) {
|
||||
case 'A':
|
||||
case 'a':
|
||||
if ((err = addTodo(db)) == ERROR)
|
||||
return;
|
||||
break;
|
||||
case 'L':
|
||||
case 'l':
|
||||
if ((err = listAll(db)) == ERROR)
|
||||
return;
|
||||
break;
|
||||
case 'C':
|
||||
case 'c':
|
||||
if ((err = markComplete(db)) == ERROR)
|
||||
return;
|
||||
break;
|
||||
case 'R':
|
||||
case 'r':
|
||||
if ((err = deleteTodo(db)) == ERROR)
|
||||
return;
|
||||
break;
|
||||
case 'U':
|
||||
case 'u':
|
||||
if ((err = updateTodo(db)) == ERROR)
|
||||
return;
|
||||
break;
|
||||
case 'Q':
|
||||
case 'q':
|
||||
printf("Thanks for using the TERMINAL TODO\nGoodbye.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ERR addTodo(sqlite3 *db) {
|
||||
char todo[128];
|
||||
char sql[256];
|
||||
printf("\tenter todo: ");
|
||||
fgets(todo, sizeof(todo), stdin);
|
||||
int loc = strcspn(todo, "\n");
|
||||
todo[loc] = '\0';
|
||||
|
||||
sprintf(sql, "insert into Todos(Id, Title, Completed) values(NULL, '%s', 0);",
|
||||
todo);
|
||||
char *errMsg = 0;
|
||||
int rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Could not write to DB: %s\n", errMsg);
|
||||
sqlite3_free(errMsg);
|
||||
return ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
enum ERR markComplete(sqlite3 *db) {
|
||||
char sql[256], mark[4];
|
||||
char *errMsg = 0;
|
||||
|
||||
printf("\tenter id to mark complete: ");
|
||||
fgets(mark, sizeof(mark), stdin);
|
||||
int id = atoi(mark);
|
||||
sprintf(sql, "update Todos set Completed=1 where id=%d;", id);
|
||||
|
||||
int rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Could not Complete TODO: %s\n", errMsg);
|
||||
sqlite3_free(errMsg);
|
||||
return ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
enum ERR deleteTodo(sqlite3 *db) {
|
||||
char sql[256], mark[4];
|
||||
char *errMsg;
|
||||
|
||||
printf("\tenter id to delete: ");
|
||||
fgets(mark, sizeof(mark), stdin);
|
||||
int id = atoi(mark);
|
||||
sprintf(sql, "delete from Todos where id=%d;", id);
|
||||
|
||||
int rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Could not delete: %s\n", errMsg);
|
||||
sqlite3_free(errMsg);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
enum ERR updateTodo(sqlite3 *db) {
|
||||
char sql[256], mark[4], todo[128];
|
||||
char *errMsg;
|
||||
printf("\tenter id to edit: ");
|
||||
fgets(mark, sizeof(mark), stdin);
|
||||
int id = atoi(mark);
|
||||
|
||||
printf("\tenter new title for Todo: ");
|
||||
fgets(todo, sizeof(todo), stdin);
|
||||
todo[strcspn(todo, "\n")] = '\0';
|
||||
|
||||
sprintf(sql, "update Todos set Title='%s' where Id=%d;", todo, id);
|
||||
|
||||
int rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Could not update Todo: %s\n", errMsg);
|
||||
sqlite3_free(errMsg);
|
||||
return ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
enum ERR listAll(sqlite3 *db) {
|
||||
sqlite3_stmt *stmt;
|
||||
const char *sql = "select * from Todos;";
|
||||
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Could not read DB: %s\n", sqlite3_errmsg(db));
|
||||
return ERROR;
|
||||
}
|
||||
printf("%-5s%-25s%s\n", "Id", "Todo", "Completed");
|
||||
printf("------------------------------------------------\n");
|
||||
|
||||
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||||
int id = sqlite3_column_int(stmt, 0);
|
||||
char *todo = (char *)sqlite3_column_text(stmt, 1);
|
||||
if (!todo) {
|
||||
todo = "NULL";
|
||||
}
|
||||
int completed = sqlite3_column_int(stmt, 2);
|
||||
char *done = "done";
|
||||
if (!completed) {
|
||||
done = "not";
|
||||
}
|
||||
printf("%-5d%-25s%s\n", id, todo, done);
|
||||
printf("------------------------------------------------\n");
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int numberTodos(sqlite3 *db) {
|
||||
int count = 0;
|
||||
sqlite3_stmt *stmt;
|
||||
const char *sql = "select count(*) from Todos;";
|
||||
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Could not get count from db: %s\n", sqlite3_errmsg(db));
|
||||
return -1;
|
||||
}
|
||||
while ((rc = sqlite3_step(stmt)) != SQLITE_DONE) {
|
||||
count = sqlite3_column_int(stmt, 0);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int completedTodos(sqlite3 *db) {
|
||||
int count = 0;
|
||||
sqlite3_stmt *stmt;
|
||||
const char *sql = "select * from Todos where Completed=1;";
|
||||
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "could not get number of complete todos: %s\n",
|
||||
sqlite3_errmsg(db));
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((rc = sqlite3_step(stmt)) != SQLITE_DONE) {
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <stdio.h>
|
||||
|
||||
void arrayInfo(int *array, int len);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
int arr[] = {0, 1, 1, 2, 3, 5, 8, 13};
|
||||
|
||||
arrayInfo(arr, 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void arrayInfo(int *array, int len) {
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
// printf("array[%d] is %d\n", i, *(array + i));
|
||||
printf("addr %p: %d\n", &(*(array + i)), array[i]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct Node {
|
||||
int data;
|
||||
struct Node *next;
|
||||
};
|
||||
|
||||
void append(struct Node *head, int data);
|
||||
void printList(struct Node *head);
|
||||
void insertAfter(struct Node *head, int key, int data);
|
||||
void deleteLast(struct Node *head);
|
||||
void deleteNode(struct Node *head, int key);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
struct Node *head = (struct Node *)malloc(sizeof(struct Node));
|
||||
printList(head);
|
||||
|
||||
append(head, 1);
|
||||
append(head, 1);
|
||||
append(head, 2);
|
||||
append(head, 3);
|
||||
append(head, 5);
|
||||
append(head, 8);
|
||||
insertAfter(head, 3, 6);
|
||||
printList(head);
|
||||
deleteLast(head);
|
||||
printList(head);
|
||||
deleteNode(head, 2);
|
||||
printList(head);
|
||||
deleteNode(head, 9);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void append(struct Node *head, int data) {
|
||||
|
||||
struct Node *newNode, *prev, *current = head;
|
||||
newNode = (struct Node *)malloc(sizeof(struct Node));
|
||||
newNode->data = data;
|
||||
|
||||
while (current) {
|
||||
prev = current;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
prev->next = newNode;
|
||||
newNode->next = current;
|
||||
}
|
||||
|
||||
void printList(struct Node *head) {
|
||||
struct Node *current = head->next;
|
||||
|
||||
if (!current) {
|
||||
printf("error: nothing to print, list is empty\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("head->");
|
||||
while (current) {
|
||||
printf("%i->", current->data);
|
||||
current = current->next;
|
||||
}
|
||||
printf("END\n");
|
||||
}
|
||||
|
||||
void insertAfter(struct Node *head, int key, int data) {
|
||||
|
||||
struct Node *current = head;
|
||||
|
||||
while (current) {
|
||||
if (current->data == key)
|
||||
break;
|
||||
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
if (!current) {
|
||||
printf("error: could not insertAfter. current is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
|
||||
newNode->data = data;
|
||||
|
||||
newNode->next = current->next;
|
||||
current->next = newNode;
|
||||
}
|
||||
|
||||
void deleteLast(struct Node *head) {
|
||||
if (!head->next) {
|
||||
printf("error: list is empty nothing to delete\n");
|
||||
return;
|
||||
}
|
||||
|
||||
struct Node *prev = NULL, *current = head;
|
||||
|
||||
while (current->next) {
|
||||
prev = current;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
prev->next = NULL;
|
||||
free(current);
|
||||
}
|
||||
|
||||
void deleteNode(struct Node *head, int key) {
|
||||
|
||||
int found = 0;
|
||||
|
||||
struct Node *prev = NULL, *current = head;
|
||||
while (current->next) {
|
||||
if (current->data == key) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
prev = current;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
// check
|
||||
if (!found) {
|
||||
printf("error: node %i not in list, nothing to delete\n", key);
|
||||
return;
|
||||
}
|
||||
//
|
||||
prev->next = current->next;
|
||||
free(current);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define size_of(arr) (sizeof(arr) / sizeof(*arr))
|
||||
|
||||
#define DEBUG(x, args...) \
|
||||
fprintf(stderr, "ERROR: %s:%u\n" x, __FILE__, __LINE__, ##args)
|
||||
|
||||
void cleanup1() { printf("cleanup1\n"); }
|
||||
void cleanup2() { printf("cleanup2\n"); }
|
||||
void cleanup3() { printf("cleanup3\n"); }
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
atexit(cleanup1);
|
||||
int i = 10;
|
||||
// while (i --> 0) {
|
||||
// printf("%d\n", i);
|
||||
// }
|
||||
while ((i--) > 0) {
|
||||
printf("%d\n", i);
|
||||
}
|
||||
|
||||
int array[200];
|
||||
printf("array[200] len: %ld\n", size_of(array));
|
||||
DEBUG("Our array should be 200! %ld\n", size_of(array));
|
||||
atexit(cleanup2);
|
||||
|
||||
int num = 11;
|
||||
//(num & 1) ? printf("odd\n") : printf("even\n");
|
||||
char *res = (num & 1) ? "odd" : "even";
|
||||
printf("%s\n", res);
|
||||
// if (num & 1) {
|
||||
// printf("odd\n");
|
||||
// } else {
|
||||
// printf("even\n");
|
||||
// }
|
||||
|
||||
atexit(cleanup3);
|
||||
int x = 5;
|
||||
printf("%d >> 1 = %d\n", x, x >> 1);
|
||||
printf("%d << 1 = %d\n", x, x << 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
#include "APIKey.h"
|
||||
#include "cJSON/cJSON.h"
|
||||
#include "request.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void parseWeather(const char *data);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
request req;
|
||||
response res;
|
||||
|
||||
simpleHttpInit(&req);
|
||||
char url[256] = "https://api.openweathermap.org/data/2.5/"
|
||||
"weather?lat=51.52&lon=-0.10&units=imperial&appid=";
|
||||
strcat(url, API_KEY);
|
||||
|
||||
// req.url = "https://catfact.ninja/fact";
|
||||
req.url = url;
|
||||
error err = simpleHttpRequest(&req, &res, JSON, GET);
|
||||
if (err != NO_ERROR) {
|
||||
printf("error: %s\n", simpleHttpErrorString(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (res.code != 200) {
|
||||
printf("response code %ld\n", res.code);
|
||||
printf("response body:\n%s\n", res.body);
|
||||
return 1;
|
||||
}
|
||||
parseWeather(res.body);
|
||||
|
||||
simpleHttpClose(&req, &res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void parseWeather(const char *data) {
|
||||
cJSON *json = cJSON_Parse(data);
|
||||
|
||||
if (!json) {
|
||||
const char *err = cJSON_GetErrorPtr();
|
||||
if (err) {
|
||||
printf("%s\n", err);
|
||||
} else {
|
||||
printf("error parsing JSON\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const cJSON *weatherArray = NULL;
|
||||
const cJSON *weather = NULL;
|
||||
const cJSON *main = NULL;
|
||||
const cJSON *temp = NULL;
|
||||
|
||||
weatherArray = cJSON_GetObjectItemCaseSensitive(json, "weather");
|
||||
cJSON_ArrayForEach(weather, weatherArray) {
|
||||
cJSON *description =
|
||||
cJSON_GetObjectItemCaseSensitive(weather, "description");
|
||||
if (!cJSON_IsString(description)) {
|
||||
printf("error parsing description\n");
|
||||
return;
|
||||
}
|
||||
printf("Weather description: %s\n", description->valuestring);
|
||||
}
|
||||
|
||||
main = cJSON_GetObjectItemCaseSensitive(json, "main");
|
||||
if (!main) {
|
||||
printf("Error parsing main\n");
|
||||
return;
|
||||
}
|
||||
temp = cJSON_GetObjectItemCaseSensitive(main, "temp");
|
||||
if (!temp) {
|
||||
printf("error parsing temp\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Temp: %.2f\n", temp->valuedouble);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct winsize win;
|
||||
/*
|
||||
* unsigned short ws_row
|
||||
* unsinged short ws_col
|
||||
* unsighed short ws_xpixel
|
||||
* unsinged short ws_ypixel
|
||||
*/
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
|
||||
|
||||
printf("Lines: %d\n", win.ws_row);
|
||||
printf("chars: %d\n", win.ws_col);
|
||||
printf("xpixel: %d\n", win.ws_xpixel);
|
||||
printf("ypixel: %d\n", win.ws_ypixel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int len(int *arr) {
|
||||
printf("sizeof arr: %d\n", (sizeof arr));
|
||||
return sizeof arr / sizeof arr[0];
|
||||
}
|
||||
|
||||
void printArray(int *arr, int len) {
|
||||
for (int i=0; i<len; i++) {
|
||||
printf("arr[%d] : %d\n", i, arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
constexpr int SIZE = 5;
|
||||
int arr[SIZE] = { 0 };
|
||||
|
||||
//printf("sizeof arr: %d\n", (sizeof arr));
|
||||
//printf("sizeof int * %d\n", (sizeof(int *)));
|
||||
|
||||
//int len = sizeof arr / sizeof arr[0];
|
||||
printf("len : %d\n", len(arr));
|
||||
printArray(arr, SIZE);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
FILE *file = fopen("words.txt", "r");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Error opening file");
|
||||
return -1;
|
||||
}
|
||||
char buffer[256];
|
||||
int lineCount = 0, wordCount = 0;
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), file)) {
|
||||
lineCount++;
|
||||
if (buffer[0] == '\n')
|
||||
continue;
|
||||
|
||||
for (int i = 0; buffer[i] != '\0'; i++) {
|
||||
if (buffer[i] == ' ' || buffer[i] == '\n') {
|
||||
wordCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("Number of Lines: %d\n", lineCount);
|
||||
printf("Number of Words: %d\n", wordCount);
|
||||
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
hey this is a file with words in it
|
||||
|
||||
it has newlines and spaces
|
||||
|
||||
lets a program to figure out the number of lines and words.
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "math.h"
|
||||
|
||||
int add(int x, int y) { return x + y; }
|
||||
int subtract(int x, int y) { return x - y; }
|
||||
double divide(int x, int y) {
|
||||
if (y == 0)
|
||||
return 0.0;
|
||||
return (double)x / y;
|
||||
}
|
||||
int mulitply(int x, int y) { return x * y; }
|
||||
int doubleVal(int x) { return x * 2; }
|
||||
int power(int x, int p) {
|
||||
int val = 1;
|
||||
for (int i = 1; i <= p; i++) {
|
||||
val *= x;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
double squareRoot(int x) {
|
||||
double sqrt, val;
|
||||
|
||||
sqrt = divide(x, 2);
|
||||
val = 0;
|
||||
|
||||
while (sqrt != val) {
|
||||
val = sqrt;
|
||||
|
||||
sqrt = (x / val + val) / 2;
|
||||
}
|
||||
return sqrt;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
int add(int x, int y);
|
||||
int subtract(int x, int y);
|
||||
double divide(int x, int y);
|
||||
int mulitply(int x, int y);
|
||||
int doubleVal(int x);
|
||||
int power(int x, int p);
|
||||
double squareRoot(int x);
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "math.h"
|
||||
#include <criterion/alloc.h>
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/internal/new_asserts.h>
|
||||
#include <criterion/new/assert.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
Test(basic, test1) { cr_assert(1 == 1); }
|
||||
|
||||
Test(basic, test2) { cr_expect(2 == 2); }
|
||||
|
||||
void setup() { printf("setup!\n"); }
|
||||
|
||||
void teardown() { printf("teardown\n"); }
|
||||
|
||||
Test(basic, setup_teardown, .init = setup, .fini = teardown) {
|
||||
cr_assert(true);
|
||||
}
|
||||
|
||||
Test(basic, signal, .signal = SIGSEGV) {
|
||||
|
||||
int arr[2] = {1, 2};
|
||||
arr[2] = 3;
|
||||
}
|
||||
|
||||
Test(basic, noSignal) {
|
||||
|
||||
int arr[2] = {1, 2};
|
||||
arr[2] = 3;
|
||||
}
|
||||
|
||||
Test(basic, fail) { cr_fail("this test will always fail until.."); }
|
||||
|
||||
Test(basic, pass) { cr_skip("feature is not implemented"); }
|
||||
|
||||
struct thing {
|
||||
int *param;
|
||||
};
|
||||
|
||||
Test(basic, memory) {
|
||||
struct thing thing1 = {.param = cr_malloc(sizeof(int))};
|
||||
|
||||
// run tests...
|
||||
cr_free(thing1.param);
|
||||
}
|
||||
|
||||
Test(math, add) { cr_assert(add(1, 1) == 2); }
|
||||
Test(math, sub) { cr_assert(subtract(5, 10) == -5); }
|
||||
Test(math, mulitpy) { cr_assert(mulitply(2, 3) == 6); }
|
||||
Test(math, sqrt25) { cr_assert(squareRoot(25) == 5.0); }
|
||||
Test(math, sqrt2) {
|
||||
double res = squareRoot(2);
|
||||
printf("sqrt2 == %.5f\n", res);
|
||||
cr_assert(epsilon_eq(flt, res, 1.4142135, 0.00001));
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
#define PORT 9090
|
||||
|
||||
char *parseRoute(const char *route) {
|
||||
|
||||
if (strcmp(route, "home") == 0) {
|
||||
return "./static/index.html";
|
||||
} else if (strcmp(route, "about") == 0) {
|
||||
return "./static/about.html";
|
||||
} else if (strcmp(route, "favicon.ico") == 0) {
|
||||
return "./static/favicon.ico";
|
||||
} else {
|
||||
return "./static/notFound.html";
|
||||
}
|
||||
}
|
||||
|
||||
void sendHtml(int *sock, const char *route) {
|
||||
// open our html file
|
||||
FILE *html = fopen(route, "r");
|
||||
if (!html) {
|
||||
perror("Error opening html file");
|
||||
return;
|
||||
}
|
||||
|
||||
char buf[BUFFER_SIZE] = {0};
|
||||
size_t read = 0;
|
||||
|
||||
char *header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
|
||||
send(*sock, header, strlen(header), 0);
|
||||
|
||||
while ((read = fread(buf, sizeof(buf[0]), BUFFER_SIZE, html)) > 0) {
|
||||
send(*sock, buf, read, 0);
|
||||
}
|
||||
fclose(html);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int serverSocket;
|
||||
|
||||
if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
perror("socket failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct sockaddr_in serverAddr;
|
||||
serverAddr.sin_family = AF_INET;
|
||||
serverAddr.sin_addr.s_addr = INADDR_ANY;
|
||||
serverAddr.sin_port = htons(PORT);
|
||||
|
||||
if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof serverAddr) <
|
||||
0) {
|
||||
perror("bind failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (listen(serverSocket, 5) < 0) {
|
||||
perror("listen failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("Server listening on port %d\n", PORT);
|
||||
|
||||
while (1) {
|
||||
|
||||
struct sockaddr_in clientAddr;
|
||||
socklen_t clientAddr_len = sizeof clientAddr;
|
||||
int *clientSocket = malloc(sizeof(int));
|
||||
|
||||
if ((*clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr,
|
||||
&clientAddr_len)) < 0) {
|
||||
perror("accept failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("Connected\n");
|
||||
|
||||
char recBuf[BUFFER_SIZE] = {0};
|
||||
recv(*clientSocket, recBuf, BUFFER_SIZE, 0);
|
||||
// printf("%s\n", recBuf);
|
||||
|
||||
char *token = recBuf + 5;
|
||||
char *route = strtok(token, " ");
|
||||
|
||||
const char *file = parseRoute(route);
|
||||
sendHtml(clientSocket, file);
|
||||
|
||||
close(*clientSocket);
|
||||
printf("disconnected client.\n\n");
|
||||
}
|
||||
|
||||
close(serverSocket);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
all:
|
||||
$(CC) -Wall server.c db.c -O2 -std=c23 -lpthread -lsqlite3 -o server
|
||||
|
||||
debug:
|
||||
$(CC) -Wall -g server.c db.c -O0 -std=c23 -lpthread -lsqlite3 -o serverDebug
|
||||
|
||||
clean:
|
||||
$(RM) -rf server serverDebug
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "db.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
sqlite3 *initDB() {
|
||||
sqlite3 *db;
|
||||
int rc = sqlite3_open("jokes.db", &db);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Cannot open database %s\n", sqlite3_errmsg(db));
|
||||
return NULL;
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
char *GetJoke(sqlite3 *db) {
|
||||
sqlite3_stmt *stmt;
|
||||
char *sql ="select joke from Jokes order by random() limit 1;";
|
||||
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Could not read DB: %s\n", sqlite3_errmsg(db));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
char *data = (char *)sqlite3_column_text(stmt, 0);
|
||||
char *joke = strdup(data);
|
||||
sqlite3_finalize(stmt);
|
||||
sqlite3_close(db);
|
||||
return joke;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool DeleteJoke(sqlite3 *db, int id) {
|
||||
char sql[64];
|
||||
char *errMsg;
|
||||
|
||||
sprintf(sql, "delete from Jokes where id=%d;", id);
|
||||
|
||||
int rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Could not delete: %s\n", errMsg);
|
||||
sqlite3_free(errMsg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NewJoke(sqlite3 *db, char *data) {
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
int JokeCount(sqlite3 *db) {
|
||||
int count = 0;
|
||||
sqlite3_stmt *stmt;
|
||||
const char *sql = "select count(*) from Jokes;";
|
||||
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Could not get count from db: %s\n", sqlite3_errmsg(db));
|
||||
return -1;
|
||||
}
|
||||
while ((rc = sqlite3_step(stmt)) != SQLITE_DONE) {
|
||||
count = sqlite3_column_int(stmt, 0);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef DB_H
|
||||
#define DB_H
|
||||
#include <sqlite3.h>
|
||||
|
||||
sqlite3 *initDB();
|
||||
|
||||
char *GetJoke(sqlite3 *db);
|
||||
bool DeleteJoke(sqlite3 *db, int id);
|
||||
bool NewJoke(sqlite3 *db, char *data);
|
||||
int JokeCount(sqlite3 *db);
|
||||
|
||||
#endif // !DB_H
|
||||
@@ -0,0 +1,12 @@
|
||||
create table Jokes (
|
||||
Id integer PRIMARY KEY NOT NULL,
|
||||
Joke text NOT NULL
|
||||
);
|
||||
|
||||
insert into Jokes values(NULL, '!false its funny because its true');
|
||||
insert into Jokes values(NULL, 'The best thing about a Boolean is that even if you are wrong, you are only off by a bit.');
|
||||
insert into Jokes values(NULL, 'javascript');
|
||||
insert into Jokes values(NULL, 'If you listen to a UNIX shell, can you hear the C?');
|
||||
insert into Jokes values(NULL, 'My code never has bugs — it just develops random undocumented features.');
|
||||
insert into Jokes values(NULL, 'I dont always test my code, but when I do, I do it in production.');
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include "db.h"
|
||||
|
||||
#define BUF_SIZE 512
|
||||
#define MAX 10
|
||||
#define PORT 9000
|
||||
|
||||
sqlite3 *db;
|
||||
|
||||
enum method_t {
|
||||
GET, DELETE, POST
|
||||
};
|
||||
|
||||
typedef struct client_t {
|
||||
int sock;
|
||||
} client_t;
|
||||
|
||||
typedef struct request_t {
|
||||
enum method_t method;
|
||||
int sock;
|
||||
char *endPoint;
|
||||
} request_t;
|
||||
|
||||
void *handleClient(void *client);
|
||||
void parseRequest(int sock, char *req);
|
||||
void getJoke(request_t request);
|
||||
void deleteJoke(request_t request);
|
||||
void newJoke(request_t request, char *data);
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
db = initDB();
|
||||
if (!db) {
|
||||
perror("error init db");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int serverSock = 0, clientSock;
|
||||
struct sockaddr_in serverAddr, clientAddr;
|
||||
pthread_t threadID = 1;
|
||||
|
||||
serverSock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (serverSock < 0) {
|
||||
perror("listen socket failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int on = 1;
|
||||
if (setsockopt(serverSock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) {
|
||||
perror("listen setsockopt failed");
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
serverAddr.sin_family = AF_INET;
|
||||
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
serverAddr.sin_port = htons(PORT);
|
||||
|
||||
if (bind(serverSock, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
|
||||
perror("failed to bind");
|
||||
}
|
||||
|
||||
if (listen(serverSock, MAX) < 0) {
|
||||
perror("failed to listen");
|
||||
}
|
||||
|
||||
|
||||
while(true) {
|
||||
socklen_t clientLen = sizeof(clientAddr);
|
||||
|
||||
if ((clientSock = accept(serverSock, (struct sockaddr *)&clientAddr, &clientLen)) < 0) {
|
||||
perror("could not accept client");
|
||||
continue;
|
||||
}
|
||||
|
||||
client_t *c = (client_t *)malloc(sizeof(client_t));
|
||||
|
||||
c->sock = clientSock;
|
||||
|
||||
if ((pthread_create(&threadID, NULL, handleClient, (void *)c)) < 0) {
|
||||
perror("Could not create pthread");
|
||||
close(clientSock);
|
||||
continue;
|
||||
}
|
||||
|
||||
pthread_join(threadID, NULL);
|
||||
free(c);
|
||||
|
||||
}
|
||||
|
||||
close(serverSock);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *handleClient(void *c) {
|
||||
client_t *client = (client_t*)c;
|
||||
if (!client) {
|
||||
perror("could not create our client_t");
|
||||
return NULL;
|
||||
}
|
||||
int read = 0;
|
||||
char buf[BUF_SIZE];
|
||||
|
||||
if ((read = recv(client->sock, buf, BUF_SIZE, 0)) <= 0) {
|
||||
perror("Client disconnected");
|
||||
close(client->sock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parseRequest(client->sock, buf);
|
||||
close(client->sock);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void parseRequest(int sock, char *req) {
|
||||
request_t httpReq;
|
||||
httpReq.sock = sock;
|
||||
|
||||
char *lines[10];
|
||||
char *token = NULL;
|
||||
|
||||
int i = 0;
|
||||
token = strtok(req, "\n");
|
||||
lines[i++] = token;
|
||||
while (token) {
|
||||
token = strtok(NULL, "\n");
|
||||
lines[i++] = token;
|
||||
}
|
||||
|
||||
char topLine[BUF_SIZE];
|
||||
strcpy(topLine, lines[0]);
|
||||
|
||||
// POST, GET, DELETE
|
||||
char *request = strtok(lines[0], " ");
|
||||
|
||||
if (strcmp(request, "POST") == 0) {
|
||||
httpReq.method = POST;
|
||||
} else if (strcmp(request, "GET") == 0) {
|
||||
httpReq.method = GET;
|
||||
} else if (strcmp(request, "DELETE") == 0) {
|
||||
httpReq.method = DELETE;
|
||||
}
|
||||
|
||||
int len = strlen(request);
|
||||
request = topLine + len;
|
||||
char *endPoint = strtok(request, " ");
|
||||
httpReq.endPoint = endPoint;
|
||||
|
||||
if (httpReq.method == GET) {
|
||||
getJoke(httpReq);
|
||||
} else if (httpReq.method == DELETE) {
|
||||
deleteJoke(httpReq);
|
||||
} else if (httpReq.method == POST) {
|
||||
newJoke(httpReq, lines[7]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void getJoke(request_t request) {
|
||||
|
||||
char *joke = GetJoke(db);
|
||||
if (joke) {
|
||||
send(request.sock, joke, strlen(joke), 0);
|
||||
} else {
|
||||
char *msg = "error getting the joke";
|
||||
send(request.sock, msg, strlen(msg), 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void deleteJoke(request_t request) {
|
||||
// /joke/{id}
|
||||
char *val = request.endPoint + 6;
|
||||
int id = atoi(val);
|
||||
|
||||
if (DeleteJoke(db, id)) {
|
||||
char msg[128];
|
||||
sprintf(msg, "deleted joke %d\n", id);
|
||||
send(request.sock, msg, strlen(msg), 0);
|
||||
} else {
|
||||
char *msg = "error deleting the joke";
|
||||
send(request.sock, msg, strlen(msg), 0);
|
||||
}
|
||||
|
||||
}
|
||||
void newJoke(request_t request, char *data) {
|
||||
|
||||
char *joke = strtok(data, ":");
|
||||
joke = strtok(NULL, ":");
|
||||
int len = strlen(joke);
|
||||
joke[len-1] = '\0';
|
||||
|
||||
if (NewJoke(db, joke)) {
|
||||
char msg[256];
|
||||
sprintf(msg, "created new joke %s\n", joke);
|
||||
send(request.sock, msg, strlen(msg), 0);
|
||||
} else {
|
||||
char *msg = "error creating new joke";
|
||||
send(request.sock, msg, strlen(msg), 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
MIT No Attribution
|
||||
|
||||
Copyright 2024 Travis Avey
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Reference in New Issue
Block a user