/* master.c * * By Jonathan Marks * j-marks@uiuc.edu * * Compiling: * Solaris: cc master.c -o master -lxnet * AIX: cc master.c -o master */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* For gethostbyname() */ #define SERVER_PORT 10000 #define CFG_FILE "servers" typedef struct { int fd; /* File descriptor for server */ char *servername; /* Name of server */ struct in_addr address; /* Net-byte-order address for host. */ } server_def; int n_server_defs = 0; server_def *server_table = NULL; int read_config_file() { char buf[1024]; char s_serverName[1024]; FILE *f_cfg; struct hostent *he_server; if (!(f_cfg = fopen(CFG_FILE, "r"))) { fprintf(stderr, "Can't open config file: %s\n", strerror(errno)); return 0; } while(fgets(buf, sizeof(buf), f_cfg)) { if (sscanf(buf, "%s", s_serverName) < 1) { fprintf(stderr, "REJECTED config file line: %s\n", buf); continue; } /* Strip newline */ if (s_serverName[strlen(s_serverName) - 1] == '\n') s_serverName[strlen(s_serverName) - 1] = '\0'; if (!(he_server = gethostbyname(s_serverName))) { fprintf(stderr, "REJECTED server %s: Can't look it up.\n", s_serverName); continue; } n_server_defs++; server_table = (server_def*) realloc(server_table, sizeof(server_def) * n_server_defs); server_table[n_server_defs - 1].servername = strdup(s_serverName); server_table[n_server_defs - 1].address = *((struct in_addr*)(he_server->h_addr_list[0])); server_table[n_server_defs - 1].fd = -1; fprintf(stderr, "ACCEPTED server %s (%s)\n", s_serverName, inet_ntoa(server_table[n_server_defs - 1].address)); } if (n_server_defs) return 1; return 0; } void give_go_signal(void) { int i; for(i=0; i 0) if(write(server_table[i].fd, "go\n", 3) < 0) { fprintf(stderr, "ERROR sending GO signal to %s: %s\n", server_table[i].servername, strerror(errno)); close(server_table[i].fd); server_table[i].fd = -1; } return; } void give_stop_signal(void) { int i; for(i=0; i 0) if(write(server_table[i].fd, "stop\n", 5) < 0) { fprintf(stderr, "ERROR sending STOP signal to %s: %s\n", server_table[i].servername, strerror(errno)); close(server_table[i].fd); server_table[i].fd = -1; } return; } void take_user_commands(void) { char s_inp[100]; int more_commands = 1; while(more_commands) { printf("(h for help)>>> "); fgets(s_inp, sizeof(s_inp), stdin); if (s_inp[strlen(s_inp) - 1] == '\n') s_inp[strlen(s_inp) - 1] = '\0'; if (!strcmp(s_inp, "h")) { /* Show help */ printf("\th\t\tShow help\n"); printf("\tgo\t\tGive GO signal to all servers.\n"); printf("\tstop\t\tGive STOP signal to all servers, then quit.\n"); printf("\tquit\t\tQuit (without stopping servers.\n"); } else if (!strcmp(s_inp, "go")) { give_go_signal(); } else if (!strcmp(s_inp, "stop")) { /* Stop servers and quit */ give_stop_signal(); more_commands = 0; } else if (!strcmp(s_inp, "quit")) { /* Exit without stopping servers */ more_commands = 0; } else { /* Don't know what they typed */ printf("Sorry, unrecognized command. Type 'h' for help.\n"); } } return; } int main(int argc, char *argv[]) { int i; struct sockaddr_in sa_server; if (!read_config_file()) { fprintf(stderr, "No server definitions. Exiting.\n"); return 1; } /* Open connections to each server */ for(i=0; i