#include #include #include #include #include #include #include #include #include #include #define BUFLEN 255 #define MLBUFLEN (10 * BUFLEN) #define ERR_MLECHO_SYNTAX "ERROR bad syntax for MLECHO\n" #define ERR_UNKNOWN_CMD "ERROR unknown command\n" #define PANIC(where) { perror(where); exit(-1); } int readline(int sd, char *buf, int buflen) { int n, rc; char c; for (n = 1; n < buflen; n++) { if ((rc = read(sd, &c, 1)) == 1) { *buf++ = c; if (c == '\n') break; } else if (rc == 0) { if (n == 1) return 0; else break; } else return -1; } *buf = 0; return n; } void write_safe(int d, const void *buf, size_t nbytes) { if (write(d, buf, nbytes) < 0) PANIC("write"); } int main(void) { int sd, csd, i, addrlen; struct sockaddr_in client_addr, local_addr; char buf[BUFLEN], info[BUFLEN], mlbuf[MLBUFLEN]; if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) PANIC("soccket"); bzero((void *) &local_addr, sizeof(struct sockaddr_in)); local_addr.sin_family = AF_INET; local_addr.sin_port = htons(9000); local_addr.sin_addr.s_addr = INADDR_ANY; if (bind(sd, (struct sockaddr *) &local_addr, sizeof(struct sockaddr_in)) < 0) PANIC("bind"); if (listen(sd, SOMAXCONN) < 0) PANIC("listen"); while (1) { addrlen = sizeof(struct sockaddr); csd = accept(sd, (struct sockaddr*) &client_addr, &addrlen); while (1) { bzero((void *) buf, BUFLEN); if (readline(csd, (char *) &buf, BUFLEN) < 0) PANIC("readline"); if (strncmp("ECHO ", buf, 5) == 0) { write_safe(csd, "REPLY ", 6); write_safe(csd, (char *) &buf[5], strlen(&buf[5])); } else if (strncmp("INFO", buf, 4) == 0) { bzero((void *) info, BUFLEN); sprintf(info, "YOURIP %s\n", inet_ntoa(client_addr.sin_addr)); write_safe(csd, info, strlen(info)); } else if (strncmp("MLECHO ", buf, 7) == 0) { if ((strlen(buf) == 10) && isdigit(buf[7])) /* 'MLECHO n' and \n */ { int mlbufidx = 0, lines, rc; lines = atoi(&buf[7]); bzero((void *) mlbuf, MLBUFLEN); for (i = 0; i < lines; i++) { rc = readline(csd, (char *) &mlbuf[mlbufidx], MLBUFLEN-mlbufidx); if (rc < 0) PANIC("readline") else mlbufidx += rc; } bzero((void *) info, BUFLEN); sprintf(info, "MLREPLY %d\n", lines); write_safe(csd, info, strlen(info)); write_safe(csd, mlbuf, strlen(mlbuf)); } else write_safe(csd, ERR_MLECHO_SYNTAX, strlen(ERR_MLECHO_SYNTAX)); } else if (strncmp("QUIT", buf, 4) == 0) break; else write_safe(csd, ERR_UNKNOWN_CMD, strlen(ERR_UNKNOWN_CMD)); } close(csd); } close(sd); /* wird nie erreicht */ }