/* * BiffSocko * server.c * this is a tcp/ip server template. It has all the basics of a tcp server * that only needs slight modifications to be integrated to any server program. * server.c will basically bind/listen/accept/fork/kill child processes/etc. * all you have to do is plug in your read/write functions in the fork() section * of child processes, located below. * * COMPILE: gcc -l insult insult.c -l pthread * * Exit Codes * 0 Success * 1 Wrong Command Line Parameters * 2 Unable to open socket() * 3 Can't bind() to port * 4 Unable to listen() to port * 5 Can't accept() connections * 6 Can't fork() * 99 SIGINT * all other abnormal return exit codes from connection functions which do the * recev/send stuff for this program */ #include #include #include #include #include #include #include #include #include #include #define PORT 2030 #define BACKLOG 200 #define NUM 1024 /***************************************************************************** * Global Variables (yucky) *****************************************************************************/ int sd; /* socket discriptor for socket function */ /***************************************************************************** * Function Definitions *****************************************************************************/ void closer(int); /* this will handle SIGINT */ void *client_function(void *sconPtr); /* function for the thread */ /***************************************************************************** * Structure definition (needed to pass the accept() descriptor) *****************************************************************************/ struct serverCon { int connectionDesc; }; int main (int argc, char *argv[]) { struct sockaddr_in home_addr; /* network address structures */ pthread_t *client; /* new client connections thread */ int con; /* number of connections */ int accept_sd; /* socket discriptor for accept function */ unsigned int alen; /* from adderlen */ struct sockaddr_in connecting_addr; /* network address structures */ struct serverCon *sconPtr; /* pointer to the accept() socket struct */ /***************************************************************************** * check for correct usage *****************************************************************************/ if(argc != 1){ fprintf(stderr, "%s does not accept arguments\n", argv[0]); exit(1); } /***************************************************************************** * open socket *****************************************************************************/ if(!(sd=socket(AF_INET, SOCK_STREAM, 0))){ fprintf(stderr, "%s is unable to create a socket. exiting\n", argv[0]); exit(2); } /***************************************************************************** * do the sockaddr_in thing for home_addr *****************************************************************************/ home_addr.sin_family = AF_INET; home_addr.sin_port = htons(PORT); home_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(home_addr.sin_zero), 0); /***************************************************************************** * binding to port *****************************************************************************/ if((bind(sd, (struct sockaddr *)&home_addr, sizeof(struct sockaddr))) == -1){ fprintf(stderr, "%s could not bind to port. exiting\n", argv[0]); close(sd); exit(3); } printf("network server running on port %d\n", PORT); /***************************************************************************** * listen to the port *****************************************************************************/ if((listen(sd, BACKLOG)) == -1){ fprintf(stderr, "%s unable to listen to port. exiting\n", argv[0]); close(sd); exit(4); } /***************************************************************************** * clean up runaway processes & catch signals for closing out nicely *****************************************************************************/ signal(SIGCHLD, SIG_IGN); signal(SIGINT, closer); /***************************************************************************** * this is the part that does the work, we will accept() the connection, * and then fork() off and run the *connection functions* *****************************************************************************/ con=0; /* hey save some space for me!! */ client = malloc (NUM * sizeof *client); while(1){ /* accept the connecting socket */ alen=sizeof(connecting_addr); if(!(accept_sd=accept(sd, (struct sockaddr *) &connecting_addr, &alen))){ fprintf(stderr, "program is unable to accept connections. exiting\n"); close(sd); exit(5); } /* start a snazzy new thread */ sconPtr = (struct serverCon *)malloc(sizeof(struct serverCon)); sconPtr->connectionDesc = accept_sd; if((pthread_create( &client[con],NULL,client_function,(void *)sconPtr))!= 0){ printf("can't create new thread .. exiting\n"); close(sd); exit(1); } pthread_detach( client[con]); /*pthread_join( client[con],NULL); */ con++; } exit(0); } /***************************************************************************** * client_function() * does the reading and writing for the network connection *****************************************************************************/ void *client_function(void *sconPtr){ #define PARMPTR ((struct serverCon *) sconPtr) char *buffer=malloc(NUM); time_t clock; int num=0; int p1max=60; int p2max=62; int p3max=61; int p1=0; int p2=0; int p3=0; char *part1[60]={"artless", "bawdy", "beslubbering", "bootless", "churlish", "cockered", "clouted", "craven", "currish", "dankish", "dissembling", "droning", "errant", "fawning", "fobbing", "froward", "frothy", "gleeking", "goatish", "gorbellied", "impertinent", "infectious", "jarring", "loggerheaded", "lumpish", "mammering", "mangled", "mewling", "paunchy", "pribbling", "puking", "puny", "qualling", "rank", "reeky", "roguish", "ruttish", "saucy", "spleeny", "spongy", "surly", "tottering", "unmuzzled", "vain", "venomed", "villainous", "warped", "wayward", "weedy", "yeasty", "cullionly", "fusty", "caluminous", "wimpled", "burly-boned", "misbegotten", "odiferous", "poisonous", "fishified", "Wart-necked" }; char *part2[62]={"base-court", "bat-fowling", "beef-witted", "beetle-headed", "boil-brained", "clapper-clawed", "clay-brained", "common-kissing", "crook-pated", "dismal-dreaming", "dizzy-eyed", "doghearted", "dread-bolted", "earth-vexing", "elf-skinned", "fat-kidneyed", "fen-sucked", "flap-mouthed", "fly-bitten", "folly-fallen", "fool-born", "full-gorged", "guts-griping", "half-faced", "hasty-witted", "hedge-born", "hell-hated", "idle-headed", "ill-breeding", "ill-nurtured", "knotty-pated", "milk-livered", "motley-minded", "onion-eyed", "plume-plucked", "pottle-deep", "pox-marked", "reeling-ripe", "rough-hewn", "rude-growing", "rump-fed", "shard-borne", "sheep-biting", "spur-galled", "swag-bellied", "tardy-gaited", "tickle-brained", "toad-spotted", "unchin-snouted", "weather-bitten", "whoreson", "malmsey-nosed", "rampallian", "lily-livered", "scurvy-valiant", "brazen-faced", "unwash'd", "bunch-back'd", "leaden-footed", "muddy-mettled", "scale-sided", "pigeon-liver'd" }; char *part3[61]={"apple-john", "baggage", "barnacle", "bladder", "boar-pig", "bugbear", "bum-bailey", "canker-blossom", "clack-dish", "clotpole", "coxcomb", "codpiece", "death-token", "dewberry", "flap-dragon", "flax-wench", "flirt-gill", "foot-licker", "fustilarian", "giglet", "gudgeon", "haggard", "harpy", "hedge-pig", "horn-beast", "hugger-mugger", "joithead", "lewdster", "lout", "maggot-pie", "malt-worm", "mammet", "measle", "minnow", "miscreant", "moldwarp", "mumble-news", "nut-hook", "pigeon-egg", "pignut", "puttock", "pumpion", "ratsbane", "scut", "skainsmate", "strumpet", "varlot", "vassal", "vassal", "whey-face", "wagtail", "knave", "blind-worm", "popinjay", "scullian", "jolt-head", "malcontent", "devil-monk", "toad", "rascal", "Basket-Cockle" }; /* * set random numbers and integers */ srand(time(&clock)); num=rand(); p1=num % p1max; num=rand(); p2=num % p2max; num=rand(); p3=num % p3max; /* * take that evil fiend */ sprintf(buffer, "thou %s %s %s\n", part1[p1], part2[p2], part3[p3]); /*read(PARMPTR->connectionDesc, buffer, NUM);*/ write(PARMPTR->connectionDesc,buffer,strlen(buffer)); close(PARMPTR->connectionDesc); memset(buffer,0,NUM); free(PARMPTR); free(buffer); return NULL; } /***************************************************************************** * closer() * this will take care of closing up the master socket descriptor upon * SIGINT or other signals. Eventually, this will also log termination * errors to syslog *****************************************************************************/ void closer(int SIGX) { printf("exiting on Signal %d\n", SIGX); close(sd); exit(99); }