|
|
1.1 ! root 1: /* ! 2: * NNTP client routines. ! 3: * ! 4: * %W% (Berkeley) %G% ! 5: */ ! 6: ! 7: #include <stdio.h> ! 8: #include <sys/types.h> ! 9: #include <sys/socket.h> ! 10: #include <netinet/in.h> ! 11: #include <netdb.h> ! 12: #include "response_codes.h" ! 13: ! 14: FILE *ser_rd_fp; ! 15: FILE *ser_wr_fp; ! 16: ! 17: /* ! 18: * server_init Get a connection to the remote news server. ! 19: * ! 20: * Parameters: "machine" is the machine to connect to. ! 21: * ! 22: * Returns: -1 on error, 0 otherwise. ! 23: * ! 24: * Side effects: Connects to server. ! 25: */ ! 26: ! 27: server_init(machine) ! 28: char *machine; ! 29: { ! 30: int sockt_rd, sockt_wr; ! 31: char line[256]; ! 32: ! 33: sockt_rd = getsocket(machine); /* Get a socket to the */ ! 34: if (sockt_rd < 0) /* server, abort on */ ! 35: return (-1); ! 36: ! 37: /* ! 38: * Now we'll make file pointers (i.e., buffered I/O) out of ! 39: * the socket file descriptor. Note that we can't just ! 40: * open a fp for reading and writing -- we have to open ! 41: * up two separate fp's, one for reading, one for writing. ! 42: */ ! 43: ! 44: if ((ser_rd_fp = fdopen(sockt_rd, "r")) == NULL) { ! 45: perror("server_init: fdopen #1"); ! 46: return (-1); ! 47: } ! 48: ! 49: sockt_wr = dup(sockt_rd); ! 50: if ((ser_wr_fp = fdopen(sockt_wr, "w")) == NULL) { ! 51: perror("server_init: fdopen #2"); ! 52: return (-1); ! 53: } ! 54: ! 55: /* Now get the server's signon message */ ! 56: ! 57: (void) get_server(line, sizeof(line)); ! 58: if (line[0] != CHAR_OK) { ! 59: (void) close(sockt_rd); ! 60: (void) close(sockt_wr); ! 61: return (-1); /* And abort if it's not good */ ! 62: } ! 63: return (0); ! 64: } ! 65: ! 66: ! 67: /* ! 68: * getsocket -- get us a socket connected to the news server. ! 69: * ! 70: * Parameters: "machine" is the machine the server is running on. ! 71: * ! 72: * Returns: Socket connected to the news server if ! 73: * all is ok, else -1 on error. ! 74: * ! 75: * Side effects: Connects to server. ! 76: * ! 77: * Errors: Printed via perror. ! 78: */ ! 79: ! 80: getsocket(machine) ! 81: char *machine; ! 82: { ! 83: int s; ! 84: struct sockaddr_in sin; ! 85: struct servent *getservbyname(), *sp; ! 86: struct hostent *gethostbyname(), *hp; ! 87: ! 88: if ((sp = getservbyname("nntp", "tcp")) == NULL) { ! 89: fprintf(stderr, "nntp/tcp: Unknown service.\n"); ! 90: return (-1); ! 91: } ! 92: ! 93: if ((hp = gethostbyname(machine)) == NULL) { ! 94: fprintf(stderr, "%s: Unknown host.\n", machine); ! 95: return (-1); ! 96: } ! 97: ! 98: bzero((char *) &sin, sizeof(sin)); ! 99: bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length); ! 100: sin.sin_family = hp->h_addrtype; ! 101: sin.sin_port = sp->s_port; ! 102: ! 103: if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { /* Get the socket */ ! 104: perror("socket"); ! 105: return (-1); ! 106: } ! 107: ! 108: /* And then connect */ ! 109: ! 110: if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { ! 111: perror("connect"); ! 112: return (-1); ! 113: } ! 114: ! 115: return (s); ! 116: } ! 117: ! 118: ! 119: /* ! 120: * put_server -- send a line of text to the server, terminating it ! 121: * with CR and LF, as per ARPA standard. ! 122: * ! 123: * Parameters: "string" is the string to be sent to the ! 124: * server. ! 125: * ! 126: * Returns: Nothing. ! 127: * ! 128: * Side effects: Talks to the server. ! 129: * ! 130: * Note: This routine flushes the buffer each time ! 131: * it is called. For large transmissions ! 132: * (i.e., posting news) don't use it. Instead, ! 133: * do the fprintf's yourself, and then a final ! 134: * fflush. ! 135: */ ! 136: ! 137: void ! 138: put_server(string) ! 139: char *string; ! 140: { ! 141: /* fprintf(stderr, ">>> %s\n", string); */ ! 142: fprintf(ser_wr_fp, "%s\r\n", string); ! 143: (void) fflush(ser_wr_fp); ! 144: } ! 145: ! 146: ! 147: /* ! 148: * get_server -- get a line of text from the server. Strips ! 149: * CR's and LF's. ! 150: * ! 151: * Parameters: "string" has the buffer space for the ! 152: * line received. ! 153: * "size" is the size of the buffer. ! 154: * ! 155: * Returns: -1 on error, 0 otherwise. ! 156: * ! 157: * Side effects: Talks to server, changes contents of "string". ! 158: */ ! 159: ! 160: get_server(string, size) ! 161: char *string; ! 162: int size; ! 163: { ! 164: register char *cp; ! 165: char *index(); ! 166: ! 167: if (fgets(string, size, ser_rd_fp) == NULL) ! 168: return (-1); ! 169: ! 170: if ((cp = index(string, '\r')) != NULL) ! 171: *cp = '\0'; ! 172: else if ((cp = index(string, '\n')) != NULL) ! 173: *cp = '\0'; ! 174: /* fprintf(stderr, "<<< %s\n", string); */ ! 175: ! 176: return (0); ! 177: } ! 178: ! 179: ! 180: /* ! 181: * close_server -- close the connection to the server, after sending ! 182: * the "quit" command. ! 183: * ! 184: * Parameters: None. ! 185: * ! 186: * Returns: Nothing. ! 187: * ! 188: * Side effects: Closes the connection with the server. ! 189: * You can't use "put_server" or "get_server" ! 190: * after this routine is called. ! 191: */ ! 192: ! 193: void ! 194: close_server() ! 195: { ! 196: char ser_line[256]; ! 197: ! 198: put_server("QUIT"); ! 199: (void) get_server(ser_line, sizeof(ser_line)); ! 200: ! 201: (void) fclose(ser_wr_fp); ! 202: (void) fclose(ser_rd_fp); ! 203: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.