ExtFunc int WaitForConnection(char *portStr) { struct sockaddr_in addr; struct hostent *host; int sockListen; socklen_t addrLen; short port; int val1; struct linger val2; if (portStr) port = atoi(portStr); /* XXX Error checking */ else port = DEFAULT_PORT; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); sockListen = socket(AF_INET, SOCK_STREAM, 0); if (sockListen < 0) die("socket"); val1 = 1; setsockopt(sockListen, SOL_SOCKET, SO_REUSEADDR, (void *)&val1, sizeof(val1)); if (bind(sockListen, (struct sockaddr *)&addr, sizeof(addr)) < 0) die("bind"); if (listen(sockListen, 1) < 0) die("listen"); addrLen = sizeof(addr); sock = accept(sockListen, (struct sockaddr *)&addr, &addrLen); if (sock < 0) die("accept"); close(sockListen); val2.l_onoff = 1; val2.l_linger = 0; setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&val2, sizeof(val2)); netGen.fd = sock; strcpy(opponentHost, "???"); if (addr.sin_family == AF_INET) { host = gethostbyaddr((void *)&addr.sin_addr, sizeof(struct in_addr), AF_INET); if (host) { strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1); opponentHost[sizeof(opponentHost)-1] = 0; } } AddEventGen(&netGen); isServer = 1; return 0; }
ExtFunc void InitRobot(char *robotProg) { int to[2], from[2]; int status; MyEvent event; signal(SIGPIPE, CatchPipe); AtExit(CloseRobot); if (pipe(to) || pipe(from)) die("pipe"); robotProcess = fork(); if (robotProcess < 0) die("fork"); if (robotProcess == 0) { dup2(to[0], STDIN_FILENO); dup2(from[1], STDOUT_FILENO); close(to[0]); close(to[1]); close(from[0]); close(from[1]); execl("/bin/sh", "sh", "-c", robotProg, NULL); die("execl failed"); } close(to[0]); close(from[1]); toRobotFd = to[1]; robotGen.fd = fromRobotFd = from[0]; if (!(toRobot = fdopen(toRobotFd, "w"))) die("fdopen"); if ((status = fcntl(fromRobotFd, F_GETFL, 0)) < 0) die("fcntl/F_GETFL"); status |= O_NONBLOCK; if (fcntl(fromRobotFd, F_SETFL, status) < 0) die("fcntl/F_SETFL"); AddEventGen(&robotGen); RobotCmd(1, "Version %d\n", ROBOT_VERSION); if (WaitMyEvent(&event, EM_robot) != E_robot) fatal("Robot didn't start successfully"); if (1 > sscanf(event.u.robot.data, "Version %d", &robotVersion) || robotVersion < 1) fatal("Invalid Version line from robot"); if (robotVersion > ROBOT_VERSION) robotVersion = ROBOT_VERSION; }
ExtFunc int InitiateConnection(char *hostStr, char *portStr) { struct sockaddr_in addr; struct hostent *host; short port; int mySock; if (portStr) port = atoi(portStr); /* XXX Error checking */ else port = DEFAULT_PORT; host = gethostbyname(hostStr); if (!host) die("gethostbyname"); assert(host->h_addrtype == AF_INET); strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1); opponentHost[sizeof(opponentHost)-1] = 0; again: memset(&addr, 0, sizeof(addr)); addr.sin_family = host->h_addrtype; memcpy(&addr.sin_addr, host->h_addr, host->h_length); addr.sin_port = htons(port); mySock = socket(AF_INET, SOCK_STREAM, 0); if (mySock < 0) die("socket"); if (connect(mySock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { if (errno != ECONNREFUSED) die("connect"); close(mySock); sleep(1); goto again; } netGen.fd = sock = mySock; AddEventGen(&netGen); return 0; }