From 1e7bf3f5e02ffa27c68f4da246c3a4d6c1968c39 Mon Sep 17 00:00:00 2001 From: Dane MacFadden Date: Fri, 25 Jul 2025 19:06:44 -0600 Subject: [PATCH] merge fix --- Makefile | 25 +++++ README.md | 6 ++ chatty | Bin 0 -> 38296 bytes liblist.a | Bin 0 -> 14760 bytes list.h | 151 ++++++++++++++++++++++++++++ list_adders.c | 142 +++++++++++++++++++++++++++ list_adders.o | Bin 0 -> 5952 bytes list_movers.c | 46 +++++++++ list_movers.o | Bin 0 -> 3696 bytes list_removers.c | 82 ++++++++++++++++ list_removers.o | Bin 0 -> 4472 bytes listtest.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 240 +++++++++++++++++++++++++++++++++++++++++++++ main.o | Bin 0 -> 15312 bytes 14 files changed, 947 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100755 chatty create mode 100644 liblist.a create mode 100644 list.h create mode 100644 list_adders.c create mode 100644 list_adders.o create mode 100644 list_movers.c create mode 100644 list_movers.o create mode 100644 list_removers.c create mode 100644 list_removers.o create mode 100644 listtest.c create mode 100644 main.c create mode 100644 main.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0d8259b --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +CC = gcc +CFLAGS = -g +CPPFLAGS = -Wall -Wextra -pedantic -std=gnu90 + +chatty: main.o liblist.a + $(CC) $(CFLAGS) -L. -o chatty main.o -llist -lpthread + +main.o: main.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o main.o main.c + +liblist.a: list_adders.o list_removers.o list_movers.o + ar -rcs liblist.a list_adders.o list_removers.o list_movers.o + +list_adders.o: list_adders.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_adders.o list_adders.c + +list_movers.o: list_movers.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_movers.o list_movers.c + +list_removers.o: list_removers.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o list_removers.o list_removers.c + + +clean: + rm -f *.o chatty liblist.a diff --git a/README.md b/README.md new file mode 100644 index 0000000..4bdc543 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +Chatty is a simple, multithreaded chat program by Dane MacFadden. +It's inspired by an assignment I did in university that was a similar project +and is intended to be an exercise in networked and multithreaded programming. +Check out Beej's guide to network programming (and his other guides) if you want +to build something similar. Much of my code is based on his client and server. +Shoutout James for helping me write the list library back in the day. diff --git a/chatty b/chatty new file mode 100755 index 0000000000000000000000000000000000000000..cc8a6d0c5b00fd3ede46b391a0bc199ee6c7b718 GIT binary patch literal 38296 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

BBfQ)QcBQCJZqQ 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 literal 0 HcmV?d00001 diff --git a/list.h b/list.h new file mode 100644 index 0000000..a5a8db8 --- /dev/null +++ b/list.h @@ -0,0 +1,151 @@ +/* + Dane MacFadden + James Hom +*/ + +#ifndef __LIST_H__ +#define __LIST_H__ + +typedef struct node { + void *data; + struct node *next; + struct node *previous; +} NODE; + +typedef struct list { + + int size; + NODE *current; + NODE *head; + NODE *tail; + +} LIST; + +/* + * Create an empty list + * Return: Pointer to new empty list + */ +LIST *ListCreate(void); + +/* + * Get the number of items in the list + * Return: Integer containing number of items + */ +int ListCount(LIST *list); + +/* + * Get the first item in the list and make it the current item + * list: Pointer to a list + * Return: Pointer to head's data + */ +void *ListFirst(LIST *list); + +/* + * Get the last item in the list and make it the current item + * list: Pointer to a list + * Return: Pointer to tail's data + */ +void *ListLast(LIST *list); + +/* Get the item in the list after the cursor and make the cursor point to it + * list: Pointer to a list + * Return: Pointer to next item's data + */ +void *ListNext(LIST *list); + +/* + * Get the item before the cursor and set the cursor to it. + * list: Pointer to a list + * Return: Pointer to previous item's data + */ +void *ListPrev(LIST *list); + +/* Get current item in list + * list: Pointer to list + * Return: Pointer to current item's data +*/ +void *ListCurr(LIST *list); + +/* + Add item to list after current item, + switch current item to the item we just added. + If current item is at the end, item is added at the end. + list: List pointer + item: Pointer to an item to add to the list + Returns: 0 if successful, -1 otherwise +*/ +int ListAdd(LIST *list, void *item); + +/* + * Insert an item right before the current item, switch cursor to new item. + * If current is the start of the list, add to the start. + * list: Pointer to list + * item: Pointer to item to add + * Return: 0 if successful, -1 otherwise + */ +int ListInsert(LIST *list, void *item); + +/* + * Add an item to the end of the list. Keep cursor where it is. + * list: Pointer to list + * item: Pointer to item to add + * Return: 0 if successful, -1 otherwise + */ +int ListAppend(LIST *list, void *item); + +/* + * Add item to the front of the list + * list: Pointer to list + * item: Pointer to item to add + * Return: 0 if successful, -1 otherwise + */ +int ListPrepend(LIST *list, void *item); + +/* + * Delete current item from list, free current item, and make next item current + * list: Pointer to list + * Return: 0 on success, -1 on failure + */ +int ListRemove(LIST *list); + +/* + * Adds list2 to the end of list1 + * Current pointer set to current pointer of list 1. List2 ceases to exist + * list1: Pointer to list1 + * list2: Pointer to list2 + */ +void ListConcat(LIST *list1, LIST *list2); + +/* + * Deletes list + * Ensure you set your pointer to NULL after calling so you don't get + * dangling pointers! + * list: Pointer to list + */ +void ListFree(LIST *list); + +/* + * Returns last item and takes it out of the list + * list: Pointer to list + * Returns Pointer to last item that was just deleted from list + */ +void *ListTrim(LIST *list); + +/* + * Search list starting at current item. + * Finishes at end of list or when a match is found + * list: Pointer to list + * comparator: Routine that returns 0 + * if the item and comparisonArg don't match, + * or 1 if they do. If a match is found the current pointer + * is left at the matched item + * If no match is found, + * current pointer is left at the end + * Return: Pointer to matching item if found, otherwise NULL pointer + */ +void *ListSearch(LIST *list, int (*comparator)(void *, void *), + void *comparisonArg); + +#endif + + diff --git a/list_adders.c b/list_adders.c new file mode 100644 index 0000000..87e3be2 --- /dev/null +++ b/list_adders.c @@ -0,0 +1,142 @@ +#include +#include + +LIST *ListCreate(void) { + LIST *new_list; + + new_list = malloc(sizeof(LIST)); + if (!new_list) { + return NULL; + } + + new_list->size = 0; + new_list->current = 0; + new_list->head = 0; + new_list->tail = 0; + + return new_list; +} + +int ListAdd(LIST *list, void *item) { + /* 3 cases + * 1. Empty list + * 2. Insert when cursor is at the tail (& list not empty) + * 3. Insert when cursor is anywhere but the tail (& list not empty) + */ + NODE *new_node = malloc(sizeof(NODE)); + if (new_node == NULL || (list->current == NULL && list->size != 0)) { + return -1; + } + new_node->data = item; + if (list->size == 0) { + list->current = new_node; + list->head = new_node; + list->tail = new_node; + } + else if (list->current == list->tail) { + new_node->previous = list->tail; + list->tail->next = new_node; + list->tail = new_node; + list->current = new_node; + } + else if (list->current != list->tail && list->size > 0) { + new_node->next = list->current->next; + new_node->previous = list->current; + list->current->next->previous = new_node; + list->current->next = new_node; + list->current = new_node; + } + else { + return -1; + } + + list->size++; + return 0; +} + +int ListInsert(LIST *list, void *item) { + /* 3 cases + * 1. Empty list + * 2. Insert when cursor is at the head (& list not empty) + * 3. Insert when cursor is anywhere but the head (& list not empty) + */ + NODE *new_node = malloc(sizeof(NODE)); + if (new_node == NULL || (list->current == NULL && list->size != 0)) { + return -1; + } + + new_node->data = item; + if (list->size == 0) { + list->current = new_node; + list->head = new_node; + list->tail = new_node; + } + else if (list->current == list->head) { + new_node->next = list->head; + list->head->previous = new_node; + list->head = new_node; + list->current = new_node; + } + else if (list->current != list->head && list->size > 0) { + new_node->next = list->current; + new_node->previous = list->current->previous; + list->current->previous->next = new_node; + list->current->previous = new_node; + list->current = new_node; + } + else { + return -1; + } + + list->size++; + return 0; +} + +int ListPrepend(LIST *list, void *item) { + NODE *new_node = malloc(sizeof(NODE)); + if (new_node == NULL) { + return -1; + } + new_node->data = item; + if (list->size == 0) { + list->current = new_node; + list->head = new_node; + list->tail = new_node; + } + new_node->next = list->head; + list->head->previous = new_node; + list->head = new_node; + list->size++; + return 0; + +} + +int ListAppend(LIST *list, void *item) { + NODE *add = malloc(sizeof(NODE)); + if (add == NULL) { + return -1; + } + add->data = item; + if (list->size == 0) { + list->current = add; + list->head = add; + list->tail = add; + } + else { + add->previous = list->tail; + list->tail->next = add; + list->tail = add; + } + list->size++; + return 0; + +} + +void ListConcat(LIST *listone, LIST *listtwo) { + listone->tail->next = listtwo->head; + listone->tail = listtwo->tail; + listone->size += listtwo->size; + free(listtwo); + listtwo = NULL; +} + diff --git a/list_adders.o b/list_adders.o new file mode 100644 index 0000000000000000000000000000000000000000..f569a994c42fe651d4c0307083e696f6225f9622 GIT binary patch literal 5952 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 literal 0 HcmV?d00001 diff --git a/list_movers.c b/list_movers.c new file mode 100644 index 0000000..12c220b --- /dev/null +++ b/list_movers.c @@ -0,0 +1,46 @@ +#include +#include + +int ListCount(LIST *list) { + return (int) list->size; +} + +void *ListFirst(LIST *list) { + if (list->size != 0) { + list->current = list->head; + return list->current->data; + } + return NULL; +} + +void *ListLast(LIST *list) { + if (list->size != 0) { + list->current = list->tail; + return list->current->data; + } + return NULL; +} + +void *ListNext(LIST *list) { + if (list->current->next != NULL) { + list->current = list->current->next; + return list->current->data; + } + return NULL; +} + +void *ListPrev(LIST *list) { + if (list->current->next != NULL) { + list->current = list->current->previous; + return list->current->data; + } + return NULL; +} + +void *ListCurr(LIST *list) { + if (list->current != NULL) { + return list->current->data; + } + return NULL; +} + diff --git a/list_movers.o b/list_movers.o new file mode 100644 index 0000000000000000000000000000000000000000..bc01d096af55088a838937cb833983143320ab21 GIT binary patch literal 3696 zcmbtWUu;uV82@hD+xD(&*R5MA?xhbC2gbI;hzJTL+Zr||5I1#+59O}Cuwr{}=^y@> zMkd3E`b2yo8Y8@s@Io*ed@&?G$eZ|LL=%JY!TDgs2NQ?E`TNd27ur$;vM>40_vif1 z@1Aq+ch0@v-1`0BZX$&s+<2f%ZZvTyWG!@_g@d`)c|pI$B( zjjXAcj4D9wd~vzHtCCS91L32lC~t66RIQ*3BaYGoQ^)jop1T(chBqijxcwaoNw~{mQPk z`PubXESLrlX|52mAH=`f zeQBEe5;g6&$fy5zf0bV4@lZr{hfXv?e;f~m*9?Ywl|EF6Ylz&TZGiySH=8JI1$!4c#4Nli0V4+zb>K;OzGi% zmRYD`UEtRL99rN=;QThOj2w%N`wX5EZo!3ZoO65bV}$i3x3Lyn%*G9i1rgb}uNfC_ z!NqMHDo)5wMp)Ol9d5x53!FCzoNo)7p8#=1#Tw(T9_<%|ylz)7X{Z3I0^;iPYe87y zN5Wd4{BC~Qiu{8Hzl54PsKvDmMvL~OynpzRhX;jm1D^< zm=4qf{_!G=(RQT6O7V3YDszo6@DTn}0MIwU_@41iW6Uh?&yV#PkeR z3vU>dLk_I8d(YT7nO5GQyk67EnaJEwQ-q374|(55uJnO=WLO&s8RTrWGv1A{5ctmnuG7+K@evhGQ4LUJoiVz@NWWZKa)dv z-Mk-eWIf_5W$y>?3-1T>Kbd&9aUt_jnD>B#Jp1#iwZq+Ac9pgj@gNI3@D1vmA8jFLNGp zzy7Osx40=fjc>k5I`uc-Af5UTVo@F%!BZ4P`6m=)!|Q}932Hl@$n$wk%!{ocjbDn8 z0X5vUs7Ae$syi^LlJ{-Zhd7A1Z&LN0PzSt=>L4O@QjJWi-QHblAEH5#aC=Xx%A!|{ zJGts{Q9;}E$e~Ah>gq-hh_!ZOtsPe9@?&dJ-@LK70)E84vHeuq_odBAyH(nC(w>!e zLE3%NrlpNb3nO^9NjnZ3!h;;y&N2SQo&VJhhNqZAr*8Q}&EuUq rWh#!Hx}@x#n^bt>auuF^^9om7y~49EX4@5)Zmm=vp(5H8h#~(04mdJV literal 0 HcmV?d00001 diff --git a/list_removers.c b/list_removers.c new file mode 100644 index 0000000..3a18fb6 --- /dev/null +++ b/list_removers.c @@ -0,0 +1,82 @@ +#include +#include + +int ListRemove(LIST *list) { + NODE *unused; + if (list->current == NULL) { + return -1; + } + if (list->size == 1) { + unused = list->current; + list->current = NULL; + list->head = NULL; + list->tail = NULL; + } + else if (list->current == list->head) { + unused = list->head; + list->head = list->head->next; + list->current = list->head; + list->current->previous = NULL; + } + else if (list->current == list->tail) { + unused = list->tail; + list->tail= list->tail->previous; + list->current = list->tail; + list->current->next = NULL; + } + else { + unused = list->current; + list->current->previous->next = list->current->next; + list->current->next->previous = list->current->previous; + list->current = list->current->next; + } + + unused->data = NULL; + free(unused->data); + unused->next = NULL; + unused->previous = NULL; + unused = NULL; + free(unused); + list->size--; + return 0; + +} + +void ListFree(LIST *list) { + ListFirst(list); + while (list->head != NULL) { + ListRemove(list); + } + free(list); + +} + +void *ListTrim(LIST *list) { + NODE *tempnode = list->tail->previous; + void *nodedata = list->tail->data; + list->tail->previous = NULL; + free(list->tail); + list->tail = tempnode; + list->size--; + return nodedata; +} + +void *ListSearch(LIST *list, int (*comparator)(void *, void*), + void *comparisonArg) { + ListFirst(list); + while (list->current != NULL) { + if ((*comparator)(list->current->data, comparisonArg)) { + break; + } + else { + ListNext(list); + } + } + + if (list->current == NULL) { + list->current = list->tail; + return NULL; + } + + return list->current; +} diff --git a/list_removers.o b/list_removers.o new file mode 100644 index 0000000000000000000000000000000000000000..cdba474806cc465982311875d3c655e50faa4542 GIT binary patch literal 4472 zcmb7HTWlOx89uYKvpc(Euh(8Xwo@S6;epJMiezRaV>k}q*ZN1-nQf2NxWfi z-Cd^*af@YBVUQq=#1ja$f`{7B2PAk%AiYRwMI;_*E9e7HNnbFc2qG$osf_u)GiRLf z#!Xp$Rk&LG*PULlPaW7k!TM9oi?BYcLsz=E-63>`^Mw zve}07e8c5kdFF`|Gq+@qTU2uqFF<8n2$M7@7D>F8&E}oi`BPbYcDCl6A^zCcMxP${ z%)-O@mC~#*nVn6-dnymFP(E3qt{HDg)%S*6DIvZrlM-SC`57+Au6XrEOH~3gDf)#FP0| z?OZe7wI;mvyTogpt?pWHP_6$Jm0t@EaZ_trzg(q+yc*g0@^gi9KAW8y^ZQ>_c#BH; z9`JY+=dizO>znZ0^H(gC9fma5JE8XTbrtngs|&mWJhkOJ@E(S_2i>*Bz_rN$I#K^J z;s}{+7vcmcm+vWbHu|tL&k(x0Lg4PcZCw%XZ=MURZ7z!o*DSHIZjEf12D&D0tcPFO zyDG$^$gR^9iyf<1_FXK3mpu9NS6I|BzF*Bj`##tXHsiP60U!EpeEN8J$Whh--EH`o3wz?$ zkNLLa!F&1b2hW=Pd3o5<2K#mmzBu}GoxQ#uMm-vG0Tmj$5I>MQ_(_Udx58rM8tt&j zT-BcRYvR&d*ehbadL?^t^W0a~u+JCX*0UdOEpxxMwap{gZ(lrpi7VHdd*6L)@4Y#0 zZf$jY{N}mQHDI}zzBBad^1hp^%h{WzTGMq)Y;4P@gKOr=+%NJ1zOp{-=NjaG?17}d zdN}WnI(&2T++GLnM>^I67{rqGfaku*vy6KBz4HYudG=sSBB$#*Vzk2_;!*G{>z-3* z9*^oyKip{Q#BsqxsCdg>_)O=f4VB?g#4g*P*p*_s0^39$Q+7{r#JFHt?->pP&fp!rAwPkJP3?dLk5aVD8zj>qIxt7FZ#I4~Xr-TV z96*FABL)~D^fC23HZD(o==mnq51a9&^q(#Y)wwrH@ofCA*xT!W(g>QYqHc(_=^L>0@^8 z$>|fRdj9Le$ELqp2TnR~mz|QGJ89?hPB}eR$<3FXa-*I;BBn6k({eh=j@KMVGBdS8 zNix%pUCYghLb)Mx6H}AZGooJjh9h$GwHi>w@h8Wg5amkV5qY~|i!#4ItN2(fROahq z&av~NVHb*GzC2%dz&oX?bmkxfyARag)Dwf-v!nT+Brx1&_di8;v-_VAyV+NmNoDIY!qHER)=_fz;@I~fF+Ils1CX1 zsL=t{=QG9^Gsa%HFB!hb4tVsy`~?JOj5sEP;vPa|jD!nlxzV4E)sE0^*BQ}mcf#t; z7{rQAdD-6&=^?}o$yu$8(J6DigW5~5PvxlFOTg3bTauNVz~Tz%8IJ+wDn&ufqwu7G ztEz{7V`$$BVLB1QvPS=@Y*E;_4)7r4G8UE2lZJVW9)=dOrVMe}=tRU`$jOWmLCQeA zC9%E;Y&{u+3B`y2RIo&d5zkE`iX?P5hc}UfIZp@JR1%0s5*CtB>-s>(IKcUSZG@qW z9|IxS3r1K+61NUZ7pyyXG5V5P7Zk9J83Qdim^^5GxZGhO2L6DPhp&x+6;OQt3=AoX zZzbM;ylq|kJBXrvRnZTC0XFn~MNca_r04^RKBMS}qDe(TWc-Mt$3bHiaQLvDlJyT=EV3?f?+BkkTj<#7{INu$T8!y!Aij}V- esZ{SG$*Y%E_9Wj}ZV0(zqf|X8$3e^>#Qy*tP#@d? literal 0 HcmV?d00001 diff --git a/listtest.c b/listtest.c new file mode 100644 index 0000000..5ff9b00 --- /dev/null +++ b/listtest.c @@ -0,0 +1,255 @@ +#include +#include +#include + +int ListPrint(LIST *list) { + if (ListFirst(list) != NULL) { + printf("%d, ", *(int*)list->current->data); + } + + while (ListNext(list) != NULL) { + printf("%d, ", *(int*)list->current->data); + } + printf("\n"); + return 0; +} + +int main(void) { + LIST *listone = ListCreate(); + LIST *listtwo = ListCreate(); + NODE *cursor, *temp; + int errors = 0; + int one = 1; + int two = 2; + int three = 3; + int four = 4; + int five = 5; + int six = 6; + int seven = 7; + + /* Adders tests */ + if (listone == NULL) { + errors++; + printf("ListCreate failed on list 1\n"); + } + if (listtwo == NULL) { + errors++; + printf("ListCreate failed on list 2\n"); + } + + /* Test each of the three cases for ListAdd */ + ListAdd(listone, &one); + if (ListCount(listone) != 1) { + printf("Error in ListAdd: ListCount expected 1 got %d\n", + ListCount(listone)); + errors++; + } + if (listone->head->data != &one) { + printf("Error in ListAdd: head data unexpected\n"); + errors++; + } + if (listone->tail->data != &one) { + printf("Error in ListAdd: tail data unexpected\n"); + errors++; + } + if (listone->current->data != &one) { + printf("Error in ListAdd: current data unexpected\n"); + errors++; + } + + /* ListAdd 2 */ + ListAdd(listone, &two); + if (ListCount(listone) != 2) { + printf("Error in ListAdd 2: ListCount expected 2 got %d\n", + ListCount(listone)); + errors++; + } + if (listone->tail->data != &two) { + printf("Error in ListAdd 2: tail data unexpected\n"); + errors++; + } + if (listone->current->data != &two) { + printf("Error in ListAdd 2: current data unexpected\n"); + errors++; + } + + /* ListAdd 3 */ + ListFirst(listone); + if (listone->current != listone->head) { + printf("Error in ListAdd 3: ListFirst didn't move cursor\n"); + errors++; + } + ListAdd(listone, &three); + if (ListCount(listone) != 3) { + printf("Error in ListAdd 3: ListCount expected 3 got %d\n", + ListCount(listone)); + errors++; + } + if (listone->head->data != &one) { + printf("Error in ListAdd 3: head data unexpected\n"); + errors++; + } + if (listone->tail->data != &two) { + printf("Error in ListAdd 3: tail data unexpected\n"); + errors++; + } + if (listone->current->data != &three) { + printf("Error in ListAdd 3: current data unexpected\n"); + errors++; + } + + ListLast(listone); + if (listone->current != listone->tail) { + printf("Error: ListLast didn't move cursor\n"); + errors++; + } + + /* List Append */ + ListFirst(listone); + cursor = listone->current; + ListAppend(listone, &four); + if (ListCount(listone) != 4) { + printf("Error in ListAppend: ListCount expected 4 got %d\n", + ListCount(listone)); + errors++; + } + if (listone->tail->data != &four) { + printf("Error in ListAppend: tail data unexpected\n"); + errors++; + } + if (listone->current != cursor) { + printf("Error in ListAppend: Cursor moved"); + errors++; + } + + ListNext(listone); + if (listone->current->data != &three) { + printf("Error: ListNext didn't move the cursor\n"); + errors++; + } + + /* List Prepend */ + cursor = listone->current; + ListPrepend(listone, &five); + if (ListCount(listone) != 5) { + printf("Error in ListPrepend: ListCount expected 5 got %d\n", + ListCount(listone)); + errors++; + } + if (listone->head->data != &five) { + printf("Error in ListPrepend: head data unexpected\n"); + errors++; + } + if (listone->current != cursor) { + printf("Error in ListPrepend: Cursor moved"); + errors++; + } + + temp = listone->current->previous; + ListPrev(listone); + if (temp != listone->current) { + printf("Error: ListPrev did not function properly\n"); + errors++; + } + + /* List Insert */ + /* Test w/ cursor at head of list */ + ListFirst(listone); + temp = listone->current; + ListInsert(listone, &six); + + if (listone->head->data != &six) { + printf("Error in ListInsert: Did not change head of list\n"); + errors++; + } + + if (ListCount(listone) != 6) { + printf("Error: ListInsert did not update count\n"); + errors++; + } + + /* Move cursor and test */ + ListNext(listone); + ListNext(listone); + + ListInsert(listone, &seven); + + if (ListCount(listone) != 7) { + printf("Error: ListInsert did not update count\n"); + errors++; + } + if (listone->current->data != &seven) { + printf("Error: ListInsert did not update current\n"); + errors++; + } + if (ListCurr(listone) != listone->current->data) { + printf("Error: ListCurr did not return current data\n"); + errors++; + } + + ListAdd(listtwo, &one); + ListAdd(listtwo, &two); + ListAdd(listtwo, &three); + ListAdd(listtwo, &four); + ListAdd(listtwo, &five); + + ListFirst(listtwo); + ListNext(listtwo); + ListNext(listtwo); + if (ListCurr(listtwo) != &three) { + printf("Error: List movers\n"); + errors++; + } + + /* Test remove */ + + ListRemove(listtwo); + if (ListCurr(listtwo) != &four) { + printf("Error: ListRemove did not move the cursor properly\n"); + errors++; + } + if (ListCount(listtwo) != 4) { + printf("Error: ListRemove did not update count\n"); + errors++; + } + + ListFirst(listtwo); + ListRemove(listtwo); + if (listtwo->head->data != &two || listtwo->current->data != &two) { + printf("Error: ListRemove did not change the head or cursor\n"); + errors++; + } + + ListLast(listtwo); + ListRemove(listtwo); + if (listtwo->tail->data != &four || listtwo->current->data != &four) { + printf("Error: ListRemove did not change the tail or cursor\n"); + errors++; + } + + /* Test concat */ + ListConcat(listone, listtwo); + listtwo = NULL; + if (ListCount(listone) != 9) { + printf("Error: ListConcat did not change list size\n"); + errors++; + } + if (listone->tail->previous->data != &two || listone->tail->data != &four) { + printf("Error: ListConcat did not concatenate properly\n"); + errors++; + } + + /* Tested free in GDB */ + ListTrim(listone); + if (listone->tail->data != &two) { + printf("Error: ListTrim did not set tail properly\n"); + errors++; + } + if (ListCount(listone) != 8) { + printf("Error: ListTrim did not change count properly\n"); + errors++; + } + printf("Finished with %d errors\n", errors); + + return 0; +} diff --git a/main.c b/main.c new file mode 100644 index 0000000..1752b83 --- /dev/null +++ b/main.c @@ -0,0 +1,240 @@ +/* + * A simple chat program by Dane MacFadden + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXBUFSIZE 30 +#define BACKLOG 10 + +LIST *receivelist, *sendlist; +pthread_mutex_t sendmut, receivemut; +int sockfd, confd; + +void *input(void *arg) { + char msg[30]; + char *copy = malloc(31); + while (1) { + printf("Type a message: "); + fgets(msg, sizeof(msg), stdin); + strcpy(copy, msg); + pthread_mutex_lock(&sendmut); + ListAppend(sendlist, copy); + pthread_mutex_unlock(&sendmut); + } + return 0; +} + +void *sender(void *arg) { + char msg[30]; + while (1) { + pthread_mutex_lock(&sendmut); + if (ListCount(sendlist) != 0) { + ListFirst(sendlist); + strcpy(msg, ListCurr(sendlist)); + ListRemove(sendlist); + } + else { + pthread_mutex_unlock(&sendmut); + continue; + } + pthread_mutex_unlock(&sendmut); + } + return 0; +} + +void *receiver(void *arg) { + char msg[30]; + char *copy = malloc(31); + while (1) { + recv(sockfd, msg, 30, 0); + if (msg[0] != '\n' && msg[0] != '\0') { + pthread_mutex_lock(&receivemut); + ListAppend(receivelist, msg); + pthread_mutex_unlock(&receivemut); + } + } + return 0; +} + +void *output(void *arg) { + char *msg; + while (1) { + pthread_mutex_lock(&receivemut); + if (ListCount(receivelist) != 0) { + ListFirst(receivelist); + msg = ListCurr(receivelist); + ListRemove(receivelist); + printf("%s\n", (char*)msg); + } + pthread_mutex_unlock(&receivemut); + } + + return 0; +} + +void *get_in_addr(struct sockaddr *sa) { + if (sa->sa_family == AF_INET) { + return &(((struct sockaddr_in*)sa)->sin_addr); + } + + return &(((struct sockaddr_in6*)sa)->sin6_addr); +} + +int main(int argc, char* argv[]) { + pthread_t input_thread, send_thread, receive_thread, output_thread; + socklen_t sin_size; + struct addrinfo *p, *q; + struct addrinfo hints; + struct addrinfo *servinfo; + struct sockaddr_storage their_addr; + char s[INET6_ADDRSTRLEN]; + char *remote_machine, *local_port, *remote_port; + int status; + int yes = 1; + + if (argc != 4) { + printf("Wrong number of arguments. Usage: ./chatty \ + \n"); + return -1; + } + + if (pthread_mutex_init(&sendmut, NULL) != 0) { + printf("Error: send mutex init failed\n"); + return -1; + } + if (pthread_mutex_init(&receivemut, NULL) != 0) { + printf("Error: receive mutex init failed\n"); + return -1; + } + + local_port = argv[1]; + remote_machine = argv[2]; + remote_port = argv[3]; + + receivelist = ListCreate(); + sendlist = ListCreate(); + + if (atoi(local_port) < atoi(remote_port)) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + if ((status = getaddrinfo(NULL, local_port, &hints, &servinfo)) != 0) { + fprintf(stderr,"getaddrinfo error: %s\n",gai_strerror(status)); + exit(1); + } + + for (p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, + p->ai_socktype, + p->ai_protocol)) == -1) { + perror("Server: socket"); + continue; + } + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, + sizeof(int)) == -1) { + perror("setsockopt"); + exit(1); + } + if (bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { + close(sockfd); + perror("Server: bind"); + continue; + } + + break; + } + if (p == NULL) { + fprintf(stderr, "Server: failed to bind socket\n"); + return 2; + } + else { + servinfo = p; + } + + freeaddrinfo(servinfo); + if (listen(sockfd, BACKLOG) == -1) { + perror("listen"); + exit(1); + } + + sin_size = sizeof their_addr; + printf("Waiting for connection...\n"); + confd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); + if (confd == -1) { + perror("accept"); + } + inet_ntop(their_addr.ss_family, + get_in_addr((struct sockaddr *)&their_addr), + s, + sizeof s); + printf("Getting chatty with %s\n", s); + } + else { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + if ((status = getaddrinfo(remote_machine, remote_port, &hints, + &servinfo)) != 0) { + fprintf(stderr,"getaddrinfo error: %s\n",gai_strerror(status)); + exit(1); + } + for (q = servinfo; q != NULL; q = q->ai_next) { + if ((sockfd = socket(q->ai_family, + q->ai_socktype, + q->ai_protocol)) == -1) { + perror("Client: socket"); + continue; + } + inet_ntop(q->ai_family, get_in_addr((struct sockaddr *)q->ai_addr), + s, sizeof s); + printf("Client: attempting connection to %s\n", s); + + if (connect(sockfd, q->ai_addr, q->ai_addrlen) == -1) { + perror("Client: connect"); + close(sockfd); + continue; + } + break; + } + + if (q == NULL) { + fprintf(stderr, "Client: failed to create socket\n"); + return 2; + } + else { + servinfo = q; + } + printf("Connected!\n"); + } + pthread_create(&input_thread, NULL, input, NULL); + pthread_create(&send_thread, NULL, sender, NULL); + pthread_create(&receive_thread, NULL, receiver, NULL); + pthread_create(&output_thread, NULL, output, NULL); + pthread_join(input_thread, NULL); + pthread_join(send_thread, NULL); + pthread_join(receive_thread, NULL); + pthread_join(output_thread, NULL); + + close(sockfd); + close(confd); + return 0; +} + diff --git a/main.o b/main.o new file mode 100644 index 0000000000000000000000000000000000000000..3e775c2a23d1ca65b5a6b9ceb199bedbcfd91292 GIT binary patch literal 15312 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