# 2.11BSD#431 - /usr/src/new/nntp/common/clientlib.c

##### Functions

    bzero             X
    close_server      X
    get_dnet_socket   X
    get_server        X
    get_tcp_socket    X
    getserverbyfile   X
    handle_server_responseX
    put_server        X
    server_init       X

##### Macros

    IPPORT_NNTP       X
    index             X

       1: #ifndef lint
       2: static char *sccsid = "@(#)clientlib.c	1.9	(Berkeley) 2/25/88";
       3: #endif
       4:
       5: /*
       6:  * NNTP client routines.
       7:  */
       8:
       9: /*
      10:  * Include configuration parameters only if we're made in the nntp tree.
      11:  */
      12:
      13: #ifdef NNTPSRC
      14: #include "../common/conf.h"
      15: #endif NNTPSRC
      16:
      17: #include <stdio.h>
      18: #include <sys/types.h>
      19: #include <sys/socket.h>
      20: #include <netinet/in.h>
      21: #ifndef EXCELAN
      22: # include <netdb.h>
      23: #endif not EXCELAN
      24:
      25: #ifdef USG
      26: # define    index   strchr
      27: #endif USG
      28:
      29: #ifdef EXCELAN
      30: # define    IPPORT_NNTP 119
      31: #endif
      32:
      33: #ifdef DECNET
      34: #include <netdnet/dn.h>
      35: #include <netdnet/dnetdb.h>
      36: #endif DECNET
      37:
      38: #include "nntp.h"
      39:
      40: FILE    *ser_rd_fp = NULL;
      41: FILE    *ser_wr_fp = NULL;
      42:
      43: /*
      44:  * getserverbyfile	Get the name of a server from a named file.
      45:  *			Handle white space and comments.
      46:  *			Use NNTPSERVER environment variable if set.
      47:  *
      48:  *	Parameters:	"file" is the name of the file to read.
      49:  *
      50:  *	Returns:	Pointer to static data area containing the
      51:  *			first non-ws/comment line in the file.
      52:  *			NULL on error (or lack of entry in file).
      53:  *
      54:  *	Side effects:	None.
      55:  */
      56:
      57: char *
      58: getserverbyfile(file)
      59: char    *file;
      60: {
      61:     register FILE   *fp;
      62:     register char   *cp;
      63:     static char buf[256];
      64:     char        *index();
      65:     char        *getenv();
      66:     char        *strcpy();
      67:
      68:     if (cp = getenv("NNTPSERVER")) {
      69:         (void) strcpy(buf, cp);
      70:         return (buf);
      71:     }
      72:
      73:     if (file == NULL)
      74:         return (NULL);
      75:
      76:     fp = fopen(file, "r");
      77:     if (fp == NULL)
      78:         return (NULL);
      79:
      80:     while (fgets(buf, sizeof (buf), fp) != NULL) {
      81:         if (*buf == '\n' || *buf == '#')
      82:             continue;
      83:         cp = index(buf, '\n');
      84:         if (cp)
      85:             *cp = '\0';
      86:         (void) fclose(fp);
      87:         return (buf);
      88:     }
      89:
      90:     (void) fclose(fp);
      91:     return (NULL);           /* No entry */
      92: }
      93:
      94:
      95: /*
      96:  * server_init  Get a connection to the remote news server.
      97:  *
      98:  *	Parameters:	"machine" is the machine to connect to.
      99:  *
     100:  *	Returns:	-1 on error
     101:  *			server's initial response code on success.
     102:  *
     103:  *	Side effects:	Connects to server.
     104:  *			"ser_rd_fp" and "ser_wr_fp" are fp's
     105:  *			for reading and writing to server.
     106:  */
     107:
     108: server_init(machine)
     109: char    *machine;
     110: {
     111:     int sockt_rd, sockt_wr;
     112:     char    line[256];
     113:     char    *index();
     114: #ifdef DECNET
     115:     char    *cp;
     116:
     117:     cp = index(machine, ':');
     118:
     119:     if (cp && cp[1] == ':') {
     120:         *cp = '\0';
     121:         sockt_rd = get_dnet_socket(machine);
     122:     } else
     123:         sockt_rd = get_tcp_socket(machine);
     124: #else
     125:     sockt_rd = get_tcp_socket(machine);
     126: #endif
     127:
     128:     if (sockt_rd < 0)
     129:         return (-1);
     130:
     131:     /*
     132: 	 * Now we'll make file pointers (i.e., buffered I/O) out of
     133: 	 * the socket file descriptor.  Note that we can't just
     134: 	 * open a fp for reading and writing -- we have to open
     135: 	 * up two separate fp's, one for reading, one for writing.
     136: 	 */
     137:
     138:     if ((ser_rd_fp = fdopen(sockt_rd, "r")) == NULL) {
     139:         perror("server_init: fdopen #1");
     140:         return (-1);
     141:     }
     142:
     143:     sockt_wr = dup(sockt_rd);
     144:     if ((ser_wr_fp = fdopen(sockt_wr, "w")) == NULL) {
     145:         perror("server_init: fdopen #2");
     146:         ser_rd_fp = NULL;       /* from above */
     147:         return (-1);
     148:     }
     149:
     150:     /* Now get the server's signon message */
     151:
     152:     (void) get_server(line, sizeof(line));
     153:     return (atoi(line));
     154: }
     155:
     156:
     157: /*
     158:  * get_tcp_socket -- get us a socket connected to the news server.
     159:  *
     160:  *	Parameters:	"machine" is the machine the server is running on.
     161:  *
     162:  *	Returns:	Socket connected to the news server if
     163:  *			all is ok, else -1 on error.
     164:  *
     165:  *	Side effects:	Connects to server.
     166:  *
     167:  *	Errors:		Printed via perror.
     168:  */
     169:
     170: get_tcp_socket(machine)
     171: char    *machine;
     172: {
     173:     int s;
     174:     struct  sockaddr_in sin;
     175: #ifndef EXCELAN
     176:     struct  servent *getservbyname(), *sp;
     177:     struct  hostent *gethostbyname(), *hp;
     178: #ifdef h_addr
     179:     int x = 0;
     180:     register char **cp;
     181: #endif h_addr
     182:
     183:     if ((sp = getservbyname("nntp", "tcp")) ==  NULL) {
     184:         fprintf(stderr, "nntp/tcp: Unknown service.\n");
     185:         return (-1);
     186:     }
     187:
     188:     if ((hp = gethostbyname(machine)) == NULL) {
     189:         fprintf(stderr, "%s: Unknown host.\n", machine);
     190:         return (-1);
     191:     }
     192:
     193:     bzero((char *) &sin, sizeof(sin));
     194:     sin.sin_family = hp->h_addrtype;
     195:     sin.sin_port = sp->s_port;
     196: #else EXCELAN
     197:     bzero((char *) &sin, sizeof(sin));
     198:     sin.sin_family = AF_INET;
     199:     sin.sin_port = htons(IPPORT_NNTP);
     200: #endif EXCELAN
     201:
     202:     /*
     203: 	 * The following is kinda gross.  The name server under 4.3
     204: 	 * returns a list of addresses, each of which should be tried
     205: 	 * in turn if the previous one fails.  However, 4.2 hostent
     206: 	 * structure doesn't have this list of addresses.
     207: 	 * Under 4.3, h_addr is a #define to h_addr_list[0].
     208: 	 * We use this to figure out whether to include the NS specific
     209: 	 * code...
     210: 	 */
     211:
     212: #ifdef  h_addr
     213:
     214:     /* get a socket and initiate connection -- use multiple addresses */
     215:
     216:     for (cp = hp->h_addr_list; cp && *cp; cp++) {
     217:         s = socket(hp->h_addrtype, SOCK_STREAM, 0);
     218:         if (s < 0) {
     219:             perror("socket");
     220:             return (-1);
     221:         }
     222:             bcopy(*cp, (char *)&sin.sin_addr, hp->h_length);
     223:
     224:         if (x < 0)
     225:             fprintf(stderr, "trying %s\n", inet_ntoa(sin.sin_addr));
     226:         x = connect(s, (struct sockaddr *)&sin, sizeof (sin));
     227:         if (x == 0)
     228:             break;
     229:                 fprintf(stderr, "connection to %s: ", inet_ntoa(sin.sin_addr));
     230:         perror("");
     231:         (void) close(s);
     232:     }
     233:     if (x < 0) {
     234:         fprintf(stderr, "giving up...\n");
     235:         return (-1);
     236:     }
     237: #else   /* no name server */
     238: #ifdef EXCELAN
     239:     if ((s = rresvport(SO_KEEPALIVE)) < 0)
     240:     {
     241:         /* Get the socket */
     242:         perror("socket");
     243:         return (-1);
     244:     }
     245:     /* set up addr for the connect */
     246:     sin.sin_addr.s_addr = rhost(machine);
     247:     if (sin.sin_addr.s_addr < 0){
     248:         fprintf(stderr, "%s: Unknown host.\n", machine);
     249:         return (-1);
     250:     }
     251:     /* And then connect */
     252:
     253:     if (connect(s, &sin) < 0) {
     254:         perror("connect");
     255:         (void) close(s);
     256:         return (-1);
     257:     }
     258: #else not EXCELAN
     259:     if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
     260:         perror("socket");
     261:         return (-1);
     262:     }
     263:
     264:     /* And then connect */
     265:
     266:     bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length);
     267:     if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
     268:         perror("connect");
     269:         (void) close(s);
     270:         return (-1);
     271:     }
     272:
     273: #endif not EXCELAN
     274: #endif
     275:
     276:     return (s);
     277: }
     278:
     279: #ifdef DECNET
     280: /*
     281:  * get_dnet_socket -- get us a socket connected to the news server.
     282:  *
     283:  *	Parameters:	"machine" is the machine the server is running on.
     284:  *
     285:  *	Returns:	Socket connected to the news server if
     286:  *			all is ok, else -1 on error.
     287:  *
     288:  *	Side effects:	Connects to server.
     289:  *
     290:  *	Errors:		Printed via nerror.
     291:  */
     292:
     293: get_dnet_socket(machine)
     294: char    *machine;
     295: {
     296:     int s, area, node;
     297:     struct  sockaddr_dn sdn;
     298:     struct  nodeent *getnodebyname(), *np;
     299:
     300:     bzero((char *) &sdn, sizeof(sdn));
     301:
     302:     switch (s = sscanf( machine, "%d%*[.]%d", &area, &node )) {
     303:         case 1:
     304:             node = area;
     305:             area = 0;
     306:         case 2:
     307:             node += area*1024;
     308:             sdn.sdn_add.a_len = 2;
     309:             sdn.sdn_family = AF_DECnet;
     310:             sdn.sdn_add.a_addr[0] = node % 256;
     311:             sdn.sdn_add.a_addr[1] = node / 256;
     312:             break;
     313:         default:
     314:             if ((np = getnodebyname(machine)) == NULL) {
     315:                 fprintf(stderr,
     316:                     "%s: Unknown host.\n", machine);
     317:                 return (-1);
     318:             } else {
     319:                 bcopy(np->n_addr,
     320:                     (char *) sdn.sdn_add.a_addr,
     321:                     np->n_length);
     322:                 sdn.sdn_add.a_len = np->n_length;
     323:                 sdn.sdn_family = np->n_addrtype;
     324:             }
     325:             break;
     326:     }
     327:     sdn.sdn_objnum = 0;
     328:     sdn.sdn_flags = 0;
     329:     sdn.sdn_objnamel = strlen("NNTP");
     330:     bcopy("NNTP", &sdn.sdn_objname[0], sdn.sdn_objnamel);
     331:
     332:     if ((s = socket(AF_DECnet, SOCK_STREAM, 0)) < 0) {
     333:         nerror("socket");
     334:         return (-1);
     335:     }
     336:
     337:     /* And then connect */
     338:
     339:     if (connect(s, (struct sockaddr *) &sdn, sizeof(sdn)) < 0) {
     340:         nerror("connect");
     341:         close(s);
     342:         return (-1);
     343:     }
     344:
     345:     return (s);
     346: }
     347: #endif
     348:
     349:
     350:
     351: /*
     352:  * handle_server_response
     353:  *
     354:  *	Print some informative messages based on the server's initial
     355:  *	response code.  This is here so inews, rn, etc. can share
     356:  *	the code.
     357:  *
     358:  *	Parameters:	"response" is the response code which the
     359:  *			server sent us, presumably from "server_init",
     360:  *			above.
     361:  *			"server" is the news server we got the
     362:  *			response code from.
     363:  *
     364:  *	Returns:	-1 if the error is fatal (and we should exit).
     365:  *			0 otherwise.
     366:  *
     367:  *	Side effects:	None.
     368:  */
     369:
     370: handle_server_response(response, server)
     371: int response;
     372: char    *server;
     373: {
     374:     switch (response) {
     375:     case OK_NOPOST:     /* fall through */
     376:             printf(
     377:     "NOTE: This machine does not have permission to post articles.\n");
     378:         printf(
     379:     "      Please don't waste your time trying.\n\n");
     380:
     381:     case OK_CANPOST:
     382:         return (0);
     383:         break;
     384:
     385:     case ERR_ACCESS:
     386:         printf(
     387:    "This machine does not have permission to use the %s news server.\n",
     388:         server);
     389:         return (-1);
     390:         break;
     391:
     392:     default:
     393:         printf("Unexpected response code from %s news server: %d\n",
     394:             server, response);
     395:         return (-1);
     396:         break;
     397:     }
     398:     /*NOTREACHED*/
     399: }
     400:
     401:
     402: /*
     403:  * put_server -- send a line of text to the server, terminating it
     404:  * with CR and LF, as per ARPA standard.
     405:  *
     406:  *	Parameters:	"string" is the string to be sent to the
     407:  *			server.
     408:  *
     409:  *	Returns:	Nothing.
     410:  *
     411:  *	Side effects:	Talks to the server.
     412:  *
     413:  *	Note:		This routine flushes the buffer each time
     414:  *			it is called.  For large transmissions
     415:  *			(i.e., posting news) don't use it.  Instead,
     416:  *			do the fprintf's yourself, and then a final
     417:  *			fflush.
     418:  */
     419:
     420: void
     421: put_server(string)
     422: char *string;
     423: {
     424: #ifdef DEBUG
     425:     fprintf(stderr, ">>> %s\n", string);
     426: #endif
     427:     fprintf(ser_wr_fp, "%s\r\n", string);
     428:     (void) fflush(ser_wr_fp);
     429: }
     430:
     431:
     432: /*
     433:  * get_server -- get a line of text from the server.  Strips
     434:  * CR's and LF's.
     435:  *
     436:  *	Parameters:	"string" has the buffer space for the
     437:  *			line received.
     438:  *			"size" is the size of the buffer.
     439:  *
     440:  *	Returns:	-1 on error, 0 otherwise.
     441:  *
     442:  *	Side effects:	Talks to server, changes contents of "string".
     443:  */
     444:
     445: get_server(string, size)
     446: char    *string;
     447: int size;
     448: {
     449:     register char *cp;
     450:     char    *index();
     451:
     452:     if (fgets(string, size, ser_rd_fp) == NULL)
     453:         return (-1);
     454:
     455:     if ((cp = index(string, '\r')) != NULL)
     456:         *cp = '\0';
     457:     else if ((cp = index(string, '\n')) != NULL)
     458:         *cp = '\0';
     459: #ifdef DEBUG
     460:     fprintf(stderr, "<<< %s\n", string);
     461: #endif
     462:
     463:     return (0);
     464: }
     465:
     466:
     467: /*
     468:  * close_server -- close the connection to the server, after sending
     469:  *		the "quit" command.
     470:  *
     471:  *	Parameters:	None.
     472:  *
     473:  *	Returns:	Nothing.
     474:  *
     475:  *	Side effects:	Closes the connection with the server.
     476:  *			You can't use "put_server" or "get_server"
     477:  *			after this routine is called.
     478:  */
     479:
     480: void
     481: close_server()
     482: {
     483:     char    ser_line[256];
     484:
     485:     if (ser_wr_fp == NULL || ser_rd_fp == NULL)
     486:         return;
     487:
     488:     put_server("QUIT");
     489:     (void) get_server(ser_line, sizeof(ser_line));
     490:
     491:     (void) fclose(ser_wr_fp);
     492:     (void) fclose(ser_rd_fp);
     493: }
     494:
     495: #ifdef USG
     496: bzero(p, l)
     497:     register char   *p;
     498:     register int    l;
     499: {
     500:     while (l-- > 0)
     501:         *p++ = 0;
     502: }
     503: #endif USG

#### Defined functions

bzero defined in line 496; used 3 times

- in line 193-197(2), 300

close_server defined in line 480; used 1 times

- in /usr/src/new/nntp/common/clientlib.h line 11

get_dnet_socket defined in line 293; used 1 times

- in line 121

get_server defined in line 445; used 3 times

- in line 152, 489
- in /usr/src/new/nntp/common/clientlib.h line 10

get_tcp_socket defined in line 170; used 2 times

- in line 123-125(2)

getserverbyfile defined in line 57; used 1 times

- in /usr/src/new/nntp/common/clientlib.h line 7

handle_server_response defined in line 370; never used
put_server defined in line 420; used 2 times

- in line 488
- in /usr/src/new/nntp/common/clientlib.h line 9

server_init defined in line 108; used 1 times

- in /usr/src/new/nntp/common/clientlib.h line 8

#### Defined variables

sccsid defined in line 2; never used

#### Defined macros

IPPORT_NNTP defined in line 30; used 1 times

- in line 199

index defined in line 26; used 7 times

- in line 64, 83, 113-117(2), 450-457(3)

Last modified: 1988-02-26 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1619 |