#include #include #include "labels.h" #define BUFSZ 80 typedef struct _LocalFile { const char *name; const char *contents; } LocalFile; typedef struct _Command { char command[BUFSZ]; char parameter[BUFSZ]; } Command; LocalFile files[] = { { "README", "Information on building your project" }, { "info.txt", "Describe your project here" }, }; int ReadInput(FILE *input, char *buf, int buflen) { BEGIN: if(fgets(buf, buflen, input) != buf) return -1; GOTINPUT: { int len = strlen(buf); /* Noted limitation: If a line is too long, the rest of the line will be interpreted as another command. */ if(buf[len-1] != '\n') { printf("Line too long: %s\n", buf); return 0; } buf[len-1] = '\0'; } return 0; } int GetFile(const char *name) { int i; for(i=sizeof(files)/sizeof(LocalFile)-1; i>=0; --i) { LocalFile *f = files+i; if(!strcmp(f->name, name)) { if(f->contents) { printf("%s\n", f->contents); SUCCESS: return 0; } } } return 1; } int ParseCommand(const char *buf, Command *cmd) { if(sscanf(buf, "%s %s", cmd->command, cmd->parameter) != 2) return 1; return 0; } int ProcessCommand(const Command *cmd) { if(!strcmp(cmd->command, "GET")) { if(GetFile(cmd->parameter)) { printf("GET: Unknown file: %s\n", cmd->parameter); return 1; } SUCCESS: return 0; } printf("Unknown command: %s\n", cmd); return 1; } void StartServer(FILE *input) { char buf[BUFSZ]; printf("Starting server...\n"); while(ReadInput(input, buf, BUFSZ) == 0) { Command cmd; /* Check for blank line (\r in Windows) */ if(buf[0] == '\r' || buf[0] == '\0') continue; if(ParseCommand(buf, &cmd)) { printf("Invalid command syntax: %s\n", buf); continue; } if(ProcessCommand(&cmd)) { printf("Command failed: %s\n", buf); continue; } } printf("Shutting down server...\n"); }