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: }