static void do_something() { char *q; if ((q = memnewline(buf, bytes_in_buf))) { do_something_server(q); } else { fd_set fdlist; FD_ZERO(&fdlist); FD_SET(0, &fdlist); FD_SET(serverfd, &fdlist); if (select(serverfd+1, &fdlist, NULL, NULL, NULL) < 0) { perror("select"); } else { if (FD_ISSET(serverfd, &fdlist)) { int n = read(serverfd, buf+bytes_in_buf, sizeof buf - bytes_in_buf); if (n == 0) { printf("\nserver dropped the connection\n"); exit(0); } else if (n < 0) { perror("read"); exit(1); } else { bytes_in_buf += n; if ((q = memnewline(buf, bytes_in_buf))) do_something_server(q); } } if (FD_ISSET(0, &fdlist)) { char buf[80]; if (fgets(buf, sizeof buf, stdin) == NULL) exit(0); //step 3 char buf1[80]; int l = strlen(lang_say); strncpy(buf1,buf,l); buf1[l]= 0; if (strcmp (buf1,lang_say) == 0){ strncpy(buf1, buf + l + 1, strlen(buf) - l); sprintf(buf,"say %s\n",buf1); send_string(buf); }else{ docmd(explode(buf)); } } } } }
static void connect_to_server() { struct hostent *hp; struct sockaddr_in r; char *q; int len, server_protocol, server_nplaces, server_nthings; if ((hp = gethostbyname(host)) == NULL) { fprintf(stderr, "%s: no such host\n", host); exit(1); } if (hp->h_addr_list[0] == NULL || hp->h_addrtype != AF_INET) { fprintf(stderr, "%s: not an internet protocol host name\n", host); exit(1); } if ((serverfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); exit(1); } memset((char *)&r, '\0', sizeof r); r.sin_family = AF_INET; memcpy((char *)&r.sin_addr, hp->h_addr_list[0], hp->h_length); r.sin_port = htons(port); if (connect(serverfd, (struct sockaddr *)&r, sizeof r) < 0) { perror("connect"); exit(1); } /* read banner line */ while (!(q = memnewline(buf, bytes_in_buf))) { if ((len = read(serverfd, buf+bytes_in_buf, sizeof buf - bytes_in_buf)) == 0) { printf("server dropped the connection\n"); exit(0); } else if (len < 0) { perror("read"); exit(1); } bytes_in_buf += len; } *q = '\0'; if (sscanf(buf, "%d%d%d", &server_protocol, &server_nplaces, &server_nthings) != 3) { fprintf(stderr, "can't parse server banner line\n"); exit(0); } if (server_protocol != PROTOCOL_VERSION) { fprintf(stderr, "protocol version mismatch\n"); exit(0); } if (server_nplaces != nplaces || server_nthings != lang_nthings) { fprintf(stderr, "server has a different map than we do\n"); exit(0); } /* remove the banner line from the already-read buffer */ len = q - buf + 1; if (bytes_in_buf > len && (buf[len] == '\r' || buf[len] == '\n')) len++; bytes_in_buf -= len; memmove(buf, buf + len, bytes_in_buf); }
/* This function is guaranteed to do at most one read(). */ char *read_line_from_server(struct server *s) { int len; char *p; /* * If we returned a line last time, that's at the beginning of buf -- * move the rest of the string over it. The bytes_in_buf value has * already been adjusted. */ if (s->nextbuf) { memmove(s->buf, s->nextbuf, s->bytes_in_buf); s->nextbuf = NULL; } /* Do a read(), unless we already have a whole line. */ if (!memnewline(s->buf, s->bytes_in_buf)) { if ((len = read(s->serfd, s->buf + s->bytes_in_buf, sizeof s->buf - s->bytes_in_buf - 1)) < 0) { perror("read"); exit(1); } if (len == 0) { printf("Server shut down.\n"); exit(0); } s->bytes_in_buf += len; } /* Now do we have a whole line? */ if ((p = memnewline(s->buf, s->bytes_in_buf))) { s->nextbuf = p + 1; /* the next line if the newline is one byte */ /* but if the newline is \r\n... */ if (s->nextbuf < s->buf + s->bytes_in_buf && *p == '\r' && *(p+1) == '\n') s->nextbuf++; /* then skip the \n too */ /* * adjust bytes_in_buf for next time. Data moved down at the * beginning of the next read_line_from_server() call. */ s->bytes_in_buf -= s->nextbuf - s->buf; *p = '\0'; /* we return a nice string */ /* Is there a subsequent line already waiting? */ s->lines_pending = !!memnewline(s->nextbuf, s->bytes_in_buf); return(s->buf); } /* * Is the buffer full even though we don't yet have a whole line? * This shouldn't happen if the server is following the protocol, but * still we don't want to infinite-loop over this. */ if (s->bytes_in_buf == sizeof s->buf - 1) { s->buf[sizeof s->buf - 1] = '\0'; s->bytes_in_buf = 0; s->lines_pending = 0; return(s->buf); /* needn't set nextbuf because there's nothing to move */ } /* No line yet. Please try again later. */ return(NULL); }