Chargen and Character Generator are out of sync, but ready for linking

remotes/1696626127813107402/master
silverwizard 4 years ago
parent ba941d6f47
commit 22da63b4bc
  1. 11
      Makefile
  2. 437
      character.c
  3. 97
      character.h
  4. 302
      chargen.c

@ -0,0 +1,11 @@
CC=cc
LIBS=-lm
generator:
${CC} -o charactergenerator ${LIBS} character.c
server:
${CC} -o chargen chargen.c
all: server generator
.PHONY: all

@ -0,0 +1,437 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "character.h"
int dieroll(int num,int sides){
int total = 0;
for(num;num>0;num--){
total = total + arc4random_uniform(sides)+1;
}
return total;
}
void addLanguage(long lang){
if((lang & languages ) == 0){
languages = languages + lang;
}else{
addLanguage(exp2l(arc4random_uniform(15)));
}
}
void addProf(long prof){
if((prof & profs) == 0){
profs = profs + prof;
}else{
addProf(exp2l(arc4random_uniform(18)));
}
}
void classProfs(unsigned long* classprofs, int count, int num){
//Remove existing profs from the array
for(int i=0; i<=count;i++){
if((classprofs[i] & profs) != 0){
classprofs[i] = classprofs[count];
count--;
i = 0;
}
}
//Shuffle the array
for(int i=0; i<=count;i++){
int newpos = i + arc4random_uniform(count - i);
unsigned long local = classprofs[newpos];
classprofs[newpos] = classprofs[i];
classprofs[i]=local;
}
//Grab the first N elements, based on the class's value, but first, if we have more profs than available profs, get some random ones
if(num > count){
for(count;num > count;count--){
addProf(exp2l(arc4random_uniform(18)));
}
}
for(int i=0;i<=num;i++){
addProf(classprofs[num]);
}
}
void genClass(){
int c = arc4random_uniform(sizeof(classes)/sizeof(classes[0]));
class = classes[c];
switch(c){
case BARBARIAN:;
unsigned long barbskills[6] = {ANIMALHANDLING, ATHLETICS, INTIMIDATION, NATURE, PERCEPTION, SURVIVAL};
hp = 12 + mods[CON];
classProfs(barbskills, 6, 2);
break;
case BARD:;
addProf(exp2l(arc4random_uniform(18)));
addProf(exp2l(arc4random_uniform(18)));
addProf(exp2l(arc4random_uniform(18)));
strlcat(otherprofs, "Three Musical Instruments, ", sizeof(otherprofs));
hp = 8 + mods[CON];
break;
case CLERIC:;
unsigned long clericskills[5]= {HISTORY, INSIGHT, MEDICINE, PERSUASION, RELIGION};
classProfs(clericskills, 5, 2);
hp = 8 + mods[CON];
break;
case DRUID:;
unsigned long druidskills[8] = {ARCANA, ANIMALHANDLING, INSIGHT, MEDICINE, NATURE, PERCEPTION, RELIGION, SURVIVAL};
classProfs(druidskills, 8, 2);
strlcat(otherprofs, "Herbalism Kit, ", sizeof(otherprofs));
hp = 8 + mods[CON];
break;
case FIGHTER:;
unsigned long fighterskills[8] = {ACROBATICS, ANIMALHANDLING, ATHLETICS, HISTORY, INSIGHT, INTIMIDATION, PERCEPTION, SURVIVAL};
classProfs(fighterskills, 8, 2);
hp = 10 + mods[CON];
break;
case MONK:;
unsigned long monkskills[6] = {ACROBATICS, ATHLETICS, HISTORY, INSIGHT, RELIGION, STEALTH};
classProfs(monkskills, 6, 2);
strlcat(otherprofs, "Artisan Tool or Musical Instrument, ", sizeof(otherprofs));
hp = 8 + mods[CON];
break;
case PALADIN:;
unsigned long paladinskills[6] = {ATHLETICS, INSIGHT, INTIMIDATION, MEDICINE, PERSUASION, RELIGION};
classProfs(paladinskills, 6, 2);
hp = 10 + mods[CON];
break;
case RANGER:;
unsigned long rangerskills[8] = {ANIMALHANDLING, ATHLETICS, INSIGHT, INVESTIGATION, NATURE, PERCEPTION, STEALTH, SURVIVAL};
classProfs(rangerskills, 8, 3);
hp = 10 + mods[CON];
break;
case ROGUE:;
unsigned long rogueskills[11] = {ACROBATICS, ATHLETICS, DECEPTION, INSIGHT, INTIMIDATION, INVESTIGATION, PERCEPTION, PERFORMANCE, PERSUASION, SLEIGHTOFHAND, STEALTH};
classProfs(rogueskills, 11, 4);
strlcat(otherprofs, "Thieves tools, ", sizeof(otherprofs));
hp = 8 + mods[CON];
break;
case SORCERER:;
unsigned long sorcererskills[6] = {ARCANA, DECEPTION, INSIGHT, INTIMIDATION, PERSUASION, RELIGION};
classProfs(sorcererskills, 6, 2);
hp = 6 + mods[CON];
break;
case WARLOCK:;
unsigned long warlockskills[7] = {ARCANA, DECEPTION, HISTORY, INTIMIDATION, INVESTIGATION, NATURE, RELIGION};
classProfs(warlockskills, 7, 2);
hp = 8 + mods[CON];
break;
case WIZARD:;
unsigned long wizardskills[5] = {ARCANA, HISTORY, INVESTIGATION, MEDICINE, RELIGION};
classProfs(wizardskills, 5, 2);
hp = 6 + mods[CON];
break;
default:
fprintf(stderr, "Incorrect class was generated for some reason");
/* This should never happen */
}
}
void genRace(){
int r = arc4random_uniform(sizeof(races)/sizeof(races[0]));
race = races[r];
int subrace;
switch (r){
case DRAGONBORN:
addLanguage(DRACONIC);
stats[STR]+=2;
stats[CHA]+=1;
break;
case DWARF:
addLanguage(DWARVISH);
stats[CON]+=2;
subrace = arc4random_uniform(2);
if(subrace == 0){
race = "Hill Dwarf";
stats[WIS]+=1;
}else{
race = "Mountain Dwarf";
stats[STR]+=2;
}
break;
case ELF:
addLanguage(ELVISH);
addProf(PERCEPTION);
stats[DEX]+=2;
subrace = arc4random_uniform(3);
if(subrace == 0){
race = "High Elf";
stats[INT]+=1;
addLanguage(exp2l(arc4random_uniform(15)));
}else if(subrace == 1){
race = "Wood Elf";
stats[WIS]+=1;
}else{
race = "Drow";
stats[CHA]+=1;
}
break;
case GNOME:
subrace = arc4random_uniform(2);
stats[INT]+=2;
addLanguage(GNOMISH);
if(subrace == 0){
race = "Forest Gnome";
stats[DEX]+=1;
}else{
race = "Rock Gnome";
stats[CON]+=1;
strlcat(otherprofs, "Artisan Tools, ", sizeof(otherprofs));
}
break;
case HALFELF:
stats[CHA]+=2;
stats[arc4random_uniform(4)]+=1;
stats[arc4random_uniform(4)]+=1;
addProf(exp2l(arc4random_uniform(18)));
addProf(exp2l(arc4random_uniform(18)));
addLanguage(exp2l(arc4random_uniform(15)));
addLanguage(ELVISH);
break;
case HALFLING:
addLanguage(HALFLISH);
stats[DEX]+=2;
subrace = arc4random_uniform(2);
if(subrace == 0){
race = "Lightfoot Halfling";
stats[CHA]+=1;
}else{
race = "Stout Halfling";
stats[INT]+=1;
}
break;
case HALFORC:
addLanguage(ORC);
stats[STR]+=2;
stats[CON]+=1;
addProf(INTIMIDATION);
break;
case HUMAN:
stats[STR]+=1;
stats[DEX]+=1;
stats[CON]+=1;
stats[INT]+=1;
stats[WIS]+=1;
stats[CHA]+=1;
addLanguage(exp2l(arc4random_uniform(15)));
break;
case TIEFLING:
stats[INT]+=1;
stats[CHA]+=2;
addLanguage(INFERNAL);
break;
default:
fprintf(stderr, "Something went wrong in race selection");
/*Hopefully should never happen*/
}
}
void genBackground(){
int b = arc4random_uniform(sizeof(backgrounds)/sizeof(backgrounds[0]));
background = backgrounds[b];
switch (b){
case ACOLYTE:
addProf(INSIGHT);
addProf(RELIGION);
addLanguage(exp2l(arc4random_uniform(15)));
addLanguage(exp2l(arc4random_uniform(15)));
break;
case CHARLATAN:
addProf(DECEPTION);
addProf(SLEIGHTOFHAND);
strlcat(otherprofs, "Disguise Kit, ", sizeof(otherprofs));
strlcat(otherprofs, "Forgery Kit, ", sizeof(otherprofs));
break;
case CRIMINAL:
addProf(DECEPTION);
addProf(STEALTH);
strlcat(otherprofs, "Gaming Set, ", sizeof(otherprofs));
strlcat(otherprofs, "Theives Tools, ", sizeof(otherprofs));
break;
case ENTERTAINER:
addProf(ACROBATICS);
addProf(PERFORMANCE);
strlcat(otherprofs, "Disguise Kit, ", sizeof(otherprofs));
strlcat(otherprofs, "Musical Instrument, ", sizeof(otherprofs));
break;
case FOLKHERO:
addProf(ANIMALHANDLING);
addProf(SURVIVAL);
strlcat(otherprofs, "Artisan's Tools, ", sizeof(otherprofs));
strlcat(otherprofs, "Land Vehicles, ", sizeof(otherprofs));
break;
case GUILDARTISAN:
addProf(INSIGHT);
addProf(PERSUASION);
addLanguage(exp2l(arc4random_uniform(15)));
strlcat(otherprofs, "Artisan's Tools, ", sizeof(otherprofs));
break;
case HERMIT:
addProf(MEDICINE);
addProf(RELIGION);
addLanguage(exp2l(arc4random_uniform(15)));
strlcat(otherprofs, "Herbalism Kit, ", sizeof(otherprofs));
break;
case NOBLE:
addProf(HISTORY);
addProf(PERSUASION);
addLanguage(exp2l(arc4random_uniform(15)));
strlcat(otherprofs, "Gaming Set, ", sizeof(otherprofs));
break;
case OUTLANDER:
addProf(ATHLETICS);
addProf(SURVIVAL);
addLanguage(exp2l(arc4random_uniform(15)));
strlcat(otherprofs, "Musical Instrument, ", sizeof(otherprofs));
break;
case SAGE:
addProf(ARCANA);
addProf(HISTORY);
addLanguage(exp2l(arc4random_uniform(15)));
addLanguage(exp2l(arc4random_uniform(15)));
break;
case SAILOR:
addProf(ATHLETICS);
addProf(PERCEPTION);
strlcat(otherprofs, "Navigator's Tools, ", sizeof(otherprofs));
strlcat(otherprofs, "Water Vehicles, ", sizeof(otherprofs));
break;
case SOLDIER:
addProf(ATHLETICS);
addProf(INTIMIDATION);
strlcat(otherprofs, "Gaming Set, ", sizeof(otherprofs));
strlcat(otherprofs, "Land Vehicles, ", sizeof(otherprofs));
break;
case URCHIN:
addProf(SLEIGHTOFHAND);
addProf(STEALTH);
strlcat(otherprofs, "Theives Tools, ", sizeof(otherprofs));
strlcat(otherprofs, "Disguise Kit, ", sizeof(otherprofs));
break;
default:
fprintf(stderr, "Bad background was generated!");
/* Ideally not reached */
}
}
int main(){
int i;
strlcat(otherprofs, "", 1);
genRace();
genClass();
genBackground();
for(i=0; i < 6; i++){
stats[i] = dieroll(3,6);
mods[i] = floor((stats[i]/2)-5);
}
printf("Race = %s\nBackground = %s\nClass = %s\nStr = %d %d\nDex = %d %d\nCon = %d %d\nInt = %d %d\nWis = %d %d\nCha = %d %d\n\nHP: %d\n", race, background, class, stats[STR], mods[STR], stats[DEX], mods[DEX], stats[CON], mods[CON], stats[INT], mods[INT], stats[WIS], mods[WIS], stats[CHA], mods[CHA], hp);
printf("Proficiences:\n");
if((ATHLETICS & profs) != 0){
printf("Athletics\n");
}
if((ACROBATICS & profs) != 0){
printf("Acrobatics\n");
}
if((SLEIGHTOFHAND & profs) != 0){
printf("Sleight of Hand\n");
}
if((STEALTH & profs) != 0){
printf("Stealth\n");
}
if((ARCANA & profs) != 0){
printf("Arcana\n");
}
if((HISTORY & profs) != 0){
printf("History\n");
}
if((INVESTIGATION & profs) != 0){
printf("Investigation\n");
}
if((NATURE & profs) != 0){
printf("Nature\n");
}
if((RELIGION & profs) != 0){
printf("Regligion\n");
}
if((ANIMALHANDLING & profs) != 0){
printf("Animal Handling\n");
}
if((INSIGHT & profs) != 0){
printf("Insight\n");
}
if((MEDICINE & profs) != 0){
printf("Medicine\n");
}
if((PERCEPTION & profs) != 0){
printf("Perception\n");
}
if((SURVIVAL & profs) != 0){
printf("Survival\n");
}
if((DECEPTION & profs) != 0){
printf("Deception\n");
}
if((INTIMIDATION & profs) != 0){
printf("Intimidation\n");
}
if((PERFORMANCE & profs) != 0){
printf("Performance\n");
}
if((PERSUASION & profs) != 0){
printf("Persuaion\n");
}
printf("\nLanguages:\nCommon\n");
if((ABYSSAL & languages) != 0){
printf("Abyssal\n");
}
if((CELESTIAL & languages) != 0){
printf("Celestial\n");
}
if((DRACONIC & languages) != 0){
printf("Draconic\n");
}
if((DEEPSPEECH & languages) != 0){
printf("Deep Speech\n");
}
if((INFERNAL & languages) != 0){
printf("Infernal\n");
}
if((PRIMORDIAL & languages) != 0){
printf("Primordial\n");
}
if((SYLVAN & languages) != 0){
printf("Sylvan\n");
}
if((UNDERCOMMON & languages) != 0){
printf("Undercommon\n");
}
if((DWARVISH & languages) != 0){
printf("Dwarvish\n");
}
if((ELVISH & languages) != 0){
printf("Elvish\n");
}
if((GIANT & languages) != 0){
printf("Giant\n");
}
if((GNOMISH & languages) != 0){
printf("Gnome\n");
}
if((GOBLIN & languages) != 0){
printf("Goblin\n");
}
if((HALFLISH & languages) != 0){
printf("Halfling\n");
}
if((ORC & languages) != 0){
printf("Orcish\n");
}
printf("\nOther Profs: %s\n", otherprofs);
return 1;
}

@ -0,0 +1,97 @@
// Define skill proficiencies for prof array
#define ATHLETICS 1
#define ACROBATICS 2
#define SLEIGHTOFHAND 4
#define STEALTH 8
#define ARCANA 16
#define HISTORY 32
#define INVESTIGATION 64
#define NATURE 128
#define RELIGION 256
#define ANIMALHANDLING 512
#define INSIGHT 1024
#define MEDICINE 2048
#define PERCEPTION 4096
#define SURVIVAL 8192
#define DECEPTION 16384
#define INTIMIDATION 32768
#define PERFORMANCE 65536
#define PERSUASION 131072
// Define language proficiences for prof array
#define ABYSSAL 1
#define CELESTIAL 2
#define DRACONIC 4
#define DEEPSPEECH 8
#define INFERNAL 16
#define PRIMORDIAL 32
#define SYLVAN 64
#define UNDERCOMMON 128
#define DWARVISH 256
#define ELVISH 512
#define GIANT 1024
#define GNOMISH 2048
#define GOBLIN 4096
#define HALFLISH 8192
#define ORC 16384
//Define values so we can make array references easier to read
#define BARBARIAN 0
#define BARD 1
#define CLERIC 2
#define DRUID 3
#define FIGHTER 4
#define MONK 5
#define PALADIN 6
#define RANGER 7
#define ROGUE 8
#define SORCERER 9
#define WARLOCK 10
#define WIZARD 11
#define DRAGONBORN 0
#define DWARF 1
#define ELF 2
#define GNOME 3
#define HALFELF 4
#define HALFLING 5
#define HALFORC 6
#define HUMAN 7
#define TIEFLING 8
#define ACOLYTE 0
#define CHARLATAN 1
#define CRIMINAL 2
#define ENTERTAINER 3
#define FOLKHERO 4
#define GUILDARTISAN 5
#define HERMIT 6
#define NOBLE 7
#define OUTLANDER 8
#define SAGE 9
#define SAILOR 10
#define SOLDIER 11
#define URCHIN 12
#define STR 0
#define DEX 1
#define CON 2
#define INT 3
#define WIS 4
#define CHA 5
unsigned long profs;
unsigned long languages;
char otherprofs[100];
char* background;
char* race;
char* class;
char* classes[] = {"Barbarian", "Bard", "Cleric", "Druid", "Fighter", "Monk", "Paladin", "Ranger", "Rogue", "Sorcerer", "Warlock", "Wizard" };
char* races[] = { "Dragonborn", "Dwarf", "Elf", "Gnome", "Half-Elf", "Halfling", "Half-Orc", "Human", "Tiefling" };
char* backgrounds[] = { "Acolyte", "Charlatan", "Criminal", "Entertainer", "Folk Hero", "Guild Artisan", "Hermit", "Noble", "Outlander", "Sage", "Sailor", "Soldier", "Urchin" };
int stats[6];
int mods[6];
int hp;

@ -0,0 +1,302 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <getopt.h>
#include <err.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <unistd.h>
#include <netdb.h>
void usage_and_die(const char *myname, const char *fmt, ...)
{
if (fmt)
{
va_list ap;
va_start(ap, fmt);
vwarnx(fmt, ap);
}
errx(EXIT_FAILURE, "Usage: %s [-4 | -6] [-u | -t] [-l listen-addr] [-p listen-port]", myname);
}
enum { MAX_LISTENERS = 8, MAX_CONNECTED = 64 };
int listen_fds[MAX_LISTENERS];
int packet_fds[MAX_LISTENERS];
int stream_fds[MAX_CONNECTED];
unsigned num_listen, num_stream, num_packet;
int main(int argc, char **argv)
{
int opt;
int ret;
char hbuf[1024];
char sbuf[32];
struct addrinfo hints = {0};
struct addrinfo *bind_addrs;
const char *listen_addr = NULL;
const char *listen_port = NULL;
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_UNSPEC;
while ((opt = getopt(argc, argv, "46l:p:tu")) != -1)
{
switch (opt)
{
case '4':
case '6':
if (hints.ai_family != AF_UNSPEC)
usage_and_die(argv[0], "-4 and -6 are incompatible (leave out to use both)");
hints.ai_family = (opt == '4') ? AF_INET : AF_INET6;
break;
case 't':
case 'u':
if (hints.ai_protocol != 0)
usage_and_die(argv[0], "-t and -u are incompatible (leave out to use both)");
hints.ai_protocol = (opt == 't') ? IPPROTO_TCP : IPPROTO_UDP;
break;
case 'l':
if (listen_addr != NULL)
usage_and_die(argv[0], "Only one listen address allowed!");
listen_addr = optarg;
break;
case 'p':
if (listen_port != NULL)
usage_and_die(argv[0], "Only one listen port allowed!");
listen_port = optarg;
break;
default:
usage_and_die(argv[0], NULL);
/* not reached */
}
}
argc -= optind;
argv += optind;
if (argc != 0)
usage_and_die(argv[0], NULL);
if (listen_port == NULL)
listen_port = "chargen";
printf("Opening listeners on %s:%s...\n", (listen_addr == NULL) ? "*" : listen_addr, listen_port);
ret = getaddrinfo(listen_addr, listen_port, &hints, &bind_addrs);
if (ret)
errx(EXIT_FAILURE, "getaddrinfo: %s", gai_strerror(ret));
for (struct addrinfo *a = bind_addrs; a != NULL; a = a->ai_next)
{
int s;
ret = getnameinfo(a->ai_addr, a->ai_addrlen, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV | (a->ai_socktype == SOCK_STREAM) ? 0 : NI_DGRAM);
if (ret)
warn("getnameinfo: %s", gai_strerror(ret));
else
printf("Opening %s listener on %s:%s...\n", (a->ai_socktype == SOCK_STREAM) ? "stream" : "packet", hbuf, sbuf);
s = socket(a->ai_family, a->ai_socktype, a->ai_protocol);
if (s == -1)
{
warn("socket");
continue;
}
if (bind(s, a->ai_addr, a->ai_addrlen) == -1)
{
warn("bind: %s:%s", hbuf, sbuf);
close(s);
continue;
}
if (a->ai_socktype == SOCK_STREAM)
{
if (listen(s, 128) == -1)
{
warn("listen");
close(s);
continue;
}
if (num_stream >= MAX_LISTENERS)
{
warnx("Listener table full, discarding %s:%s", hbuf, sbuf);
close(s);
}
else
listen_fds[num_listen++] = s;
}
else
{
if (num_packet >= MAX_LISTENERS)
{
warnx("Listener table full, discarding %s:%s", hbuf, sbuf);
close(s);
}
else
packet_fds[num_packet++] = s;
}
}
if (num_packet + num_listen == 0)
errx(EXIT_FAILURE, "No listeners to run on!\n");
if (pledge("stdio inet error", NULL) == -1)
warn("pledge");
while(1)
{
fd_set r, w;
int maxfd = 0;
union
{
struct sockaddr_in a4;
struct sockaddr_in6 a6;
} addr;
/* 64k = max UDP payload size */
static unsigned char data[64 * 1024];
FD_ZERO(&r);
FD_ZERO(&w);
if (num_stream < MAX_CONNECTED)
{
for (unsigned i = 0; i < num_listen; i++)
{
FD_SET(listen_fds[i], &r);
if (listen_fds[i] > maxfd)
maxfd = listen_fds[i];
}
}
for (unsigned i = 0; i < num_packet; i++)
{
FD_SET(packet_fds[i], &r);
if (packet_fds[i] > maxfd)
maxfd = packet_fds[i];
}
for (unsigned i = 0; i < num_stream; i++)
{
FD_SET(stream_fds[i], &r);
FD_SET(stream_fds[i], &w);
if (stream_fds[i] > maxfd)
maxfd = stream_fds[i];
}
ret = select(maxfd+1, &r, &w, NULL, NULL);
if (ret == -1)
err(EXIT_FAILURE, "select");
if (ret == 0)
{
printf("Huh, that's weird, select says nothing ready but I didn't ask for a timeout\n");
continue;
}
for (unsigned i = 0; i < num_listen; i++)
{
int l = listen_fds[i];
if (FD_ISSET(l, &r))
{
struct sockaddr *sa = (struct sockaddr *)&addr;
socklen_t len = sizeof addr;
int s = accept(l, sa, &len);
if (s == -1)
{
warn("accept");
continue;
}
stream_fds[num_stream++] = s;
ret = getnameinfo(sa, len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV);
if (ret)
warn("getnameinfo: %s", gai_strerror(ret));
else
printf("Accepting stream connection from %s:%s...\n", hbuf, sbuf);
}
if (num_stream >= MAX_CONNECTED)
break;
}
for (unsigned i = 0; i < num_packet; i++)
{
int s = packet_fds[i];
if (FD_ISSET(s, &r))
{
ssize_t rval;
struct sockaddr *sa = (struct sockaddr *)&addr;
socklen_t len = sizeof addr;
rval = recvfrom(s, data, sizeof data, 0, sa, &len);
if (rval == -1)
{
warn("recvfrom");
continue;
}
ret = getnameinfo(sa, len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV);
if (ret)
warn("getnameinfo: %s", gai_strerror(ret));
else
printf("Responding to packet from %s:%s...\n", hbuf, sbuf);
rval = sendto(s, "chargen data\r\n", 14, 0, sa, len);
if (rval == -1)
warn("sendto");
}
}
for (unsigned i = 0; i < num_stream; i++)
{
int s = stream_fds[i];
if (FD_ISSET(s, &r))
{
ssize_t rval;
rval = read(s, data, sizeof data);
if (rval <= 0)
{
if (rval == -1)
warn("read");
printf("Closing stream connection\n");
close(s);
/*
* We will miss checking the socket we move down to fill the gap we're leaving.
* That's OK, if it's ready we'll get it next time.
*/
stream_fds[i] = stream_fds[--num_stream];
continue;
}
/* Ignore data from a successful read */
}
if (FD_ISSET(s, &w))
{
if (s == 0)
{
printf("WTF? i=%u num_stream=%u stream_fds[i]=%d s=%d\n", i, num_stream, stream_fds[i], s);
continue;
}
if (write(s, "chargen data\r\n", 14) == -1)
{
warn("write");
printf("Closing stream connection\n");
close(s);
/*
* We will miss checking the socket we move down to fill the gap we're leaving.
* That's OK, if it's ready we'll get it next time.
*/
stream_fds[i] = stream_fds[--num_stream];
continue;
}
}
}
}
/* not reached */
}
Loading…
Cancel
Save