# 2.11BSD#431 - /usr/src/usr.sbin/named/tools/nslookup/list.c

##### Functions

    Finger            X
    ListHost_close    X
    ListHosts         X
    ListHostsByType   X
    PrintListInfo     X
    ViewList          X

##### Macros

    HASH_SIZE         X
    NAME_FORMAT       X

       1: /*
       2:  * Copyright (c) 1985,1989 Regents of the University of California.
       3:  * All rights reserved.
       4:  *
       5:  * Redistribution and use in source and binary forms are permitted provided
       6:  * that: (1) source distributions retain this entire copyright notice and
       7:  * comment, and (2) distributions including binaries display the following
       8:  * acknowledgement:  ``This product includes software developed by the
       9:  * University of California, Berkeley and its contributors'' in the
      10:  * documentation or other materials provided with the distribution and in
      11:  * all advertising materials mentioning features or use of this software.
      12:  * Neither the name of the University nor the names of its contributors may
      13:  * be used to endorse or promote products derived from this software without
      14:  * specific prior written permission.
      15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
      16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
      17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
      18:  */
      19:
      20: #if !defined(lint) && defined(DOSCCS)
      21: static char sccsid[] = "@(#)list.c	5.20 (Berkeley) 6/1/90";
      22: #endif
      23:
      24: /*
      25:  *******************************************************************************
      26:  *
      27:  *  list.c --
      28:  *
      29:  *	Routines to obtain info from name and finger servers.
      30:  *
      31:  *	Adapted from 4.3BSD BIND ns_init.c and from finger.c.
      32:  *
      33:  *******************************************************************************
      34:  */
      35:
      36: #include <sys/types.h>
      37: #include <sys/socket.h>
      38: #include <netinet/in.h>
      39: #include <netdb.h>
      40: #include <stdio.h>
      41: #include <string.h>
      42: #include <ctype.h>
      43: #include <errno.h>
      44: #include <arpa/nameser.h>
      45: #include <arpa/inet.h>
      46: #include <resolv.h>
      47: #include "res.h"
      48:
      49: /*
      50:  *  Imported from res_debug.c
      51:  */
      52: extern char *_res_resultcodes[];
      53:
      54: extern int errno;
      55:
      56: typedef union {
      57:     HEADER qb1;
      58:     char qb2[PACKETSZ];
      59: } querybuf;
      60:
      61: extern HostInfo *defaultPtr;
      62: extern HostInfo curHostInfo;
      63: extern int  curHostValid;
      64: extern int  queryType;
      65: extern int  queryClass;
      66:
      67: static int sockFD = -1;
      68: static int ListSubr();
      69:
      70: /*
      71:  *  During a listing to a file, hash marks are printed
      72:  *  every HASH_SIZE records.
      73:  */
      74:
      75: #define HASH_SIZE 50
      76:
      77:
      78: /*
      79:  *******************************************************************************
      80:  *
      81:  *  ListHosts --
      82:  *  ListHostsByType --
      83:  *
      84:  *	Requests the name server to do a zone transfer so we
      85:  *	find out what hosts it knows about.
      86:  *
      87:  *	For ListHosts, there are five types of output:
      88:  *	- Internet addresses (default)
      89:  *	- cpu type and operating system (-h option)
      90:  *	- canonical and alias names  (-a option)
      91:  *	- well-known service names  (-s option)
      92:  *	- ALL records (-d option)
      93:  *	ListHostsByType prints records of the default type or of a speicific
      94:  *	type.
      95:  *
      96:  *	To see all types of information sorted by name, do the following:
      97:  *	  ls -d domain.edu > file
      98:  *	  view file
      99:  *
     100:  *  Results:
     101:  *	SUCCESS		the listing was successful.
     102:  *	ERROR		the server could not be contacted because
     103:  *			a socket could not be obtained or an error
     104:  *			occured while receiving, or the output file
     105:  *			could not be opened.
     106:  *
     107:  *******************************************************************************
     108:  */
     109:
     110: void
     111: ListHostsByType(string, putToFile)
     112:     char *string;
     113:     int putToFile;
     114: {
     115:     int i, qtype, result;
     116:     char    *namePtr;
     117:     char    name[NAME_LEN];
     118:     char    option[NAME_LEN];
     119:
     120:     /*
     121: 	 *  Parse the command line. It maybe of the form "ls -t domain"
     122: 	 *  or "ls -t type domain".
     123: 	 */
     124:
     125:     i = sscanf(string, " ls -t %s %s", option, name);
     126:     if (putToFile && i == 2 && name[0] == '>') {
     127:         i--;
     128:     }
     129:     if (i == 2) {
     130:         qtype = StringToType(option, -1);
     131:         if (qtype == -1)
     132:         return;
     133:         namePtr = name;
     134:     } else if (i == 1) {
     135:         namePtr = option;
     136:         qtype = queryType;
     137:     } else {
     138:         fprintf(stderr, "*** ls: invalid request %s\n",string);
     139:         return;
     140:     }
     141:     result = ListSubr(qtype, namePtr, putToFile ? string : NULL);
     142:     if (result != SUCCESS)
     143:         fprintf(stderr, "*** Can't list domain %s: %s\n",
     144:             namePtr, DecodeError(result));
     145: }
     146:
     147: void
     148: ListHosts(string, putToFile)
     149:     char *string;
     150:     int  putToFile;
     151: {
     152:     int i, qtype, result;
     153:     char    *namePtr;
     154:     char    name[NAME_LEN];
     155:     char    option[NAME_LEN];
     156:
     157:     /*
     158: 	 *  Parse the command line. It maybe of the form "ls domain",
     159: 	 *  "ls -X domain".
     160: 	 */
     161:     i = sscanf(string, " ls %s %s", option, name);
     162:     if (putToFile && i == 2 && name[0] == '>') {
     163:         i--;
     164:     }
     165:     if (i == 2) {
     166:         if (strcmp("-a", option) == 0) {
     167:         qtype = T_CNAME;
     168:         } else if (strcmp("-h", option) == 0) {
     169:         qtype = T_HINFO;
     170:         } else if (strcmp("-m", option) == 0) {
     171:         qtype = T_MX;
     172:         } else if (strcmp("-s", option) == 0) {
     173:         qtype = T_WKS;
     174:         } else if (strcmp("-d", option) == 0) {
     175:         qtype = T_ANY;
     176:         } else {
     177:         qtype = T_A;
     178:         }
     179:         namePtr = name;
     180:     } else if (i == 1) {
     181:         namePtr = option;
     182:         qtype = T_A;
     183:     } else {
     184:         fprintf(stderr, "*** ls: invalid request %s\n",string);
     185:         return;
     186:     }
     187:     result = ListSubr(qtype, namePtr, putToFile ? string : NULL);
     188:     if (result != SUCCESS)
     189:         fprintf(stderr, "*** Can't list domain %s: %s\n",
     190:             namePtr, DecodeError(result));
     191: }
     192:
     193: static int
     194: ListSubr(qtype, domain, cmd)
     195:     int qtype;
     196:     char *domain;
     197:     char *cmd;
     198: {
     199:     querybuf        buf;
     200:     struct sockaddr_in  sin;
     201:     HEADER          *headerPtr;
     202:     int         msglen;
     203:     int         amtToRead;
     204:     int         numRead;
     205:     int         numAnswers = 0;
     206:     int         result;
     207:     int         soacnt = 0;
     208:     u_short         len;
     209:     char            *cp, *nmp;
     210:     char            dname[2][NAME_LEN];
     211:     char            file[NAME_LEN];
     212:     static char     *answer = NULL;
     213:     static int      answerLen = 0;
     214:     enum {
     215:         NO_ERRORS,
     216:         ERR_READING_LEN,
     217:         ERR_READING_MSG,
     218:         ERR_PRINTING,
     219:     } error = NO_ERRORS;
     220:
     221:     /*
     222: 	 *  Create a query packet for the requested domain name.
     223: 	 */
     224:     msglen = res_mkquery(QUERY, domain, queryClass, T_AXFR,
     225:                 (char *)0, 0, (char *)0,
     226:                 (char *) &buf, sizeof(buf));
     227:     if (msglen < 0) {
     228:         if (_res.options & RES_DEBUG) {
     229:         fprintf(stderr, "*** ls: res_mkquery failed\n");
     230:         }
     231:         return (ERROR);
     232:     }
     233:
     234:     bzero((char *)&sin, sizeof(sin));
     235:     sin.sin_family  = AF_INET;
     236:     sin.sin_port    = htons(nsport);
     237:
     238:     /*
     239: 	 *  Check to see if we have the address of the server or the
     240: 	 *  address of a server who knows about this domain.
     241: 	 *
     242: 	 *  For now, just use the first address in the list.
     243: 	 */
     244:
     245:     if (defaultPtr->addrList != NULL) {
     246:       sin.sin_addr = *(struct in_addr *) defaultPtr->addrList[0];
     247:     } else {
     248:       sin.sin_addr = *(struct in_addr *)defaultPtr->servers[0]->addrList[0];
     249:     }
     250:
     251:     /*
     252: 	 *  Set up a virtual circuit to the server.
     253: 	 */
     254:     if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
     255:         perror("ls: socket");
     256:         return(ERROR);
     257:     }
     258:     if (connect(sockFD, &sin, sizeof(sin)) < 0) {
     259:         int e;
     260:         if (errno == ECONNREFUSED) {
     261:         e = NO_RESPONSE;
     262:         } else {
     263:         perror("ls: connect");
     264:         e = ERROR;
     265:         }
     266:         (void) close(sockFD);
     267:         sockFD = -1;
     268:         return e;
     269:     }
     270:
     271:     /*
     272: 	 * Send length & message for zone transfer
     273: 	 */
     274:
     275:         len = htons(msglen);
     276:
     277:         if (write(sockFD, (char *)&len, sizeof(len)) != sizeof(len) ||
     278:             write(sockFD, (char *) &buf, msglen) != msglen) {
     279:         perror("ls: write");
     280:         (void) close(sockFD);
     281:         sockFD = -1;
     282:         return(ERROR);
     283:     }
     284:
     285:     fprintf(stdout,"[%s]\n",
     286:         (defaultPtr->addrList != NULL) ? defaultPtr->name :
     287:          defaultPtr->servers[0]->name);
     288:
     289:     if (cmd == NULL) {
     290:         filePtr = stdout;
     291:     } else {
     292:         filePtr = OpenFile(cmd, file);
     293:             if (filePtr == NULL) {
     294:                 fprintf(stderr, "*** Can't open %s for writing\n", file);
     295:         (void) close(sockFD);
     296:         sockFD = -1;
     297:                 return(ERROR);
     298:             }
     299:         fprintf(filePtr, "> %s\n", cmd);
     300:         fprintf(filePtr,"[%s]\n",
     301:         (defaultPtr->addrList != NULL) ? defaultPtr->name :
     302:          defaultPtr->servers[0]->name);
     303:     }
     304:
     305: #if 0
     306:     if (qtype == T_CNAME) {
     307:         fprintf(filePtr, "%-30s", "Alias");
     308:     } else if (qtype == T_TXT) {
     309:         fprintf(filePtr, "%-30s", "Key");
     310:     } else {
     311:         fprintf(filePtr, "%-30s", "Host or domain name");
     312:     }
     313:     switch (qtype) {
     314:         case T_A:
     315:             fprintf(filePtr, " %-30s\n", "Internet Address");
     316:             break;
     317:         case T_HINFO:
     318:             fprintf(filePtr, " %-30s\n", "CPU & OS");
     319:             break;
     320:         case T_CNAME:
     321:             fprintf(filePtr, " %-30s\n", "Canonical Name");
     322:             break;
     323:         case T_MX:
     324:             fprintf(filePtr, " %-30s\n", "Metric & Host");
     325:             break;
     326:         case T_WKS:
     327:             fprintf(filePtr, " %-4s %s\n", "Protocol", "Services");
     328:             break;
     329:         case T_MB:
     330:             fprintf(filePtr, " %-30s\n", "Mailbox");
     331:             break;
     332:         case T_MG:
     333:             fprintf(filePtr, " %-30s\n", "Mail Group");
     334:             break;
     335:         case T_MR:
     336:             fprintf(filePtr, " %-30s\n", "Mail Rename");
     337:             break;
     338:         case T_MINFO:
     339:             fprintf(filePtr, " %-30s\n", "Mail List Requests & Errors");
     340:             break;
     341:         case T_UINFO:
     342:             fprintf(filePtr, " %-30s\n", "User Information");
     343:             break;
     344:         case T_UID:
     345:             fprintf(filePtr, " %-30s\n", "User ID");
     346:             break;
     347:         case T_GID:
     348:             fprintf(filePtr, " %-30s\n", "Group ID");
     349:             break;
     350:         case T_TXT:
     351:             fprintf(filePtr, " %-30s\n", "Text");
     352:             break;
     353:         case T_NS:
     354:             fprintf(filePtr, " %-30s\n", "Name Servers");
     355:             break;
     356:         case T_PTR:
     357:             fprintf(filePtr, " %-30s\n", "Pointers");
     358:             break;
     359:         case T_SOA:
     360:             fprintf(filePtr, " %-30s\n", "Start of Authority");
     361:             break;
     362:         case T_ANY:
     363:             fprintf(filePtr, " %-30s\n", "Resource Record Info.");
     364:             break;
     365:     }
     366: #endif
     367:
     368:
     369:     dname[0][0] = '\0';
     370:     while (1) {
     371:         unsigned short tmp;
     372:
     373:         /*
     374: 	     * Read the length of the response.
     375: 	     */
     376:
     377:         cp = (char *) &tmp;
     378:         amtToRead = sizeof(u_short);
     379:         while (amtToRead > 0 && (numRead=read(sockFD, cp, amtToRead)) > 0) {
     380:         cp    += numRead;
     381:         amtToRead -= numRead;
     382:         }
     383:         if (numRead <= 0) {
     384:         error = ERR_READING_LEN;
     385:         break;
     386:         }
     387:
     388:         if ((len = htons(tmp)) == 0) {
     389:         break;  /* nothing left to read */
     390:         }
     391:
     392:         /*
     393: 	     * The server sent too much data to fit the existing buffer --
     394: 	     * allocate a new one.
     395: 	     */
     396:         if (len > answerLen) {
     397:         if (answerLen != 0) {
     398:             free(answer);
     399:         }
     400:         answerLen = len;
     401:         answer = Malloc(answerLen);
     402:         }
     403:
     404:         /*
     405: 	     * Read the response.
     406: 	     */
     407:
     408:         amtToRead = len;
     409:         cp = answer;
     410:         while (amtToRead > 0 && (numRead=read(sockFD, cp, amtToRead)) > 0) {
     411:         cp += numRead;
     412:         amtToRead -= numRead;
     413:         }
     414:         if (numRead <= 0) {
     415:         error = ERR_READING_MSG;
     416:         break;
     417:         }
     418:
     419:         result = PrintListInfo(filePtr, answer, cp, qtype, dname[0]);
     420:         if (result != SUCCESS) {
     421:         error = ERR_PRINTING;
     422:         break;
     423:         }
     424:
     425:         numAnswers++;
     426:         if (cmd != NULL && ((numAnswers % HASH_SIZE) == 0)) {
     427:         fprintf(stdout, "#");
     428:         fflush(stdout);
     429:         }
     430:         cp = answer + sizeof(HEADER);
     431:         if (ntohs(((HEADER* )answer)->qdcount) > 0)
     432:         cp += dn_skipname(cp, answer + len) + QFIXEDSZ;
     433:         nmp = cp;
     434:         cp += dn_skipname(cp, (u_char *)answer + len);
     435:         if ((_getshort(cp) == T_SOA)) {
     436:         dn_expand(answer, answer + len, nmp, dname[soacnt],
     437:             sizeof(dname[0]));
     438:             if (soacnt) {
     439:             if (strcmp(dname[0], dname[1]) == 0)
     440:             break;
     441:         } else
     442:             soacnt++;
     443:         }
     444:     }
     445:
     446:     if (cmd != NULL) {
     447:         fprintf(stdout, "%sReceived %d record%s.\n",
     448:         (numAnswers >= HASH_SIZE) ? "\n" : "",
     449:         numAnswers,
     450:         (numAnswers != 1) ? "s" : "");
     451:     }
     452:
     453:     (void) close(sockFD);
     454:     sockFD = -1;
     455:     if (cmd != NULL && filePtr != NULL) {
     456:         fclose(filePtr);
     457:         filePtr = NULL;
     458:     }
     459:
     460:     switch (error) {
     461:         case NO_ERRORS:
     462:         return (SUCCESS);
     463:
     464:         case ERR_READING_LEN:
     465:         return(ERROR);
     466:
     467:         case ERR_PRINTING:
     468:         return(result);
     469:
     470:         case ERR_READING_MSG:
     471:         headerPtr = (HEADER *) answer;
     472:         fprintf(stderr,"*** ls: error receiving zone transfer:\n");
     473:         fprintf(stderr,
     474:            "  result: %s, answers = %d, authority = %d, additional = %d\n",
     475:             _res_resultcodes[headerPtr->rcode],
     476:             ntohs(headerPtr->ancount), ntohs(headerPtr->nscount),
     477:             ntohs(headerPtr->arcount));
     478:         return(ERROR);
     479:         default:
     480:         return(ERROR);
     481:     }
     482: }
     483:
     484:
     485: /*
     486:  *******************************************************************************
     487:  *
     488:  *  PrintListInfo --
     489:  *
     490:  *	Used by the ListInfo routine to print the answer
     491:  *	received from the name server. Only the desired
     492:  *	information is printed.
     493:  *
     494:  *  Results:
     495:  *	SUCCESS		the answer was printed without a problem.
     496:  *	NO_INFO		the answer packet did not contain an answer.
     497:  *	ERROR		the answer was malformed.
     498:  *      Misc. errors	returned in the packet header.
     499:  *
     500:  *******************************************************************************
     501:  */
     502:
     503: #define NAME_FORMAT " %-30s"
     504:
     505: static Boolean
     506: strip_domain(string, domain)
     507:     char *string, *domain;
     508: {
     509:     register char *dot;
     510:
     511:     if (*domain != '\0') {
     512:     dot = string;
     513:     while ((dot = strchr(dot, '.')) != NULL && strcasecmp(domain, ++dot))
     514:         ;
     515:     if (dot != NULL) {
     516:         dot[-1] = '\0';
     517:         return TRUE;
     518:     }
     519:     }
     520:     return FALSE;
     521: }
     522:
     523:
     524: PrintListInfo(file, msg, eom, qtype, domain)
     525:     FILE    *file;
     526:     char    *msg, *eom;
     527:     int     qtype;
     528:     char    *domain;
     529: {
     530:     register char   *cp;
     531:     HEADER      *headerPtr;
     532:     int         type, class, dlen, nameLen;
     533:     u_long      ttl;
     534:     int         n, pref;
     535:     struct in_addr  inaddr;
     536:     char        name[NAME_LEN];
     537:     char        name2[NAME_LEN];
     538:     Boolean     stripped;
     539:
     540:     /*
     541:      * Read the header fields.
     542:      */
     543:     headerPtr = (HEADER *)msg;
     544:     cp = msg + sizeof(HEADER);
     545:     if (headerPtr->rcode != NOERROR) {
     546:     return(headerPtr->rcode);
     547:     }
     548:
     549:     /*
     550:      *  We are looking for info from answer resource records.
     551:      *  If there aren't any, return with an error. We assume
     552:      *  there aren't any question records.
     553:      */
     554:
     555:     if (ntohs(headerPtr->ancount) == 0) {
     556:     return(NO_INFO);
     557:     } else {
     558:     if (ntohs(headerPtr->qdcount) > 0) {
     559:         nameLen = dn_skipname(cp, eom);
     560:         if (nameLen < 0)
     561:         return (ERROR);
     562:         cp += nameLen + QFIXEDSZ;
     563:     }
     564:     if ((nameLen = dn_expand(msg, eom, cp, name, sizeof(name))) < 0)
     565:         return (ERROR);
     566:     cp += nameLen;
     567:
     568:     type = _getshort(cp);
     569:     cp += sizeof(u_short);
     570:
     571:     if (!(type == qtype || qtype == T_ANY) &&
     572:         !((type == T_NS || type == T_PTR) && qtype == T_A))
     573:         return(SUCCESS);
     574:
     575:     class = _getshort(cp);
     576:     cp += sizeof(u_short);
     577:     ttl = _getlong(cp);
     578:     cp += sizeof(u_long);
     579:     dlen = _getshort(cp);
     580:     cp += sizeof(u_short);
     581:
     582:     if (name[0] == 0)
     583:         strcpy(name, "(root)");
     584:
     585:     /* Strip the domain name from the data, if desired. */
     586:     stripped = FALSE;
     587:     if ((_res.options & RES_DEBUG) == 0) {
     588:         if (type != T_SOA) {
     589:         stripped = strip_domain(name, domain);
     590:         }
     591:     }
     592:     if (!stripped && nameLen < sizeof(name)-1) {
     593:         strcat(name, ".");
     594:     }
     595:
     596:     fprintf(file, NAME_FORMAT, name);
     597:
     598:     if (qtype == T_ANY) {
     599:         if (_res.options & RES_DEBUG) {
     600:         fprintf(file,"\t%lu %-5s", ttl, p_class(queryClass));
     601:         }
     602:         fprintf(file," %-5s", p_type(type));
     603:     }
     604:
     605:     /* XXX merge this into debug.c's print routines */
     606:
     607:     switch (type) {
     608:         case T_A:
     609:         if (class == C_IN) {
     610:             bcopy(cp, (char *)&inaddr, sizeof(inaddr));
     611:             if (dlen == 4) {
     612:             fprintf(file," %s", inet_ntoa(inaddr));
     613:             } else if (dlen == 7) {
     614:             fprintf(file," %s", inet_ntoa(inaddr));
     615:             fprintf(file," (%d, %d)", cp[4],(cp[5] << 8) + cp[6]);
     616:             } else
     617:             fprintf(file, " (dlen = %d?)", dlen);
     618:         }
     619:         break;
     620:
     621:         case T_CNAME:
     622:         case T_MB:
     623:         case T_MG:
     624:         case T_MR:
     625:         if ((nameLen =
     626:             dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
     627:             fprintf(file, " ***\n");
     628:             return (ERROR);
     629:         }
     630:         fprintf(file, " %s", name2);
     631:         break;
     632:
     633:         case T_NS:
     634:         case T_PTR:
     635:         putc(' ', file);
     636:         if (qtype != T_ANY)
     637:             fprintf(file,"%s = ", type == T_PTR ? "host" : "server");
     638:         cp = Print_cdname2(cp, msg, eom, file);
     639:         break;
     640:
     641:         case T_HINFO:
     642:         if (n = *cp++) {
     643:             (void)sprintf(name,"%.*s", n, cp);
     644:             fprintf(file," %-10s", name);
     645:             cp += n;
     646:         } else {
     647:             fprintf(file," %-10s", " ");
     648:         }
     649:         if (n = *cp++) {
     650:             fprintf(file,"  %.*s", n, cp);
     651:             cp += n;
     652:         }
     653:         break;
     654:
     655:         case T_SOA:
     656:         if ((nameLen =
     657:             dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
     658:             fprintf(file, " ***\n");
     659:             return (ERROR);
     660:         }
     661:         cp += nameLen;
     662:         fprintf(file, " %s", name2);
     663:         if ((nameLen =
     664:             dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
     665:             fprintf(file, " ***\n");
     666:             return (ERROR);
     667:         }
     668:         cp += nameLen;
     669:         fprintf(file, " %s. (", name2);
     670:         for (n = 0; n < 5; n++) {
     671:             u_long u;
     672:
     673:             u = _getlong(cp);
     674:             cp += sizeof(u_long);
     675:             fprintf(file,"%s%lu", n? " " : "", u);
     676:         }
     677:         fprintf(file, ")");
     678:         break;
     679:
     680:         case T_MX:
     681:         pref = _getshort(cp);
     682:         cp += sizeof(u_short);
     683:         fprintf(file," %-3d ",pref);
     684:         if ((nameLen =
     685:             dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
     686:             fprintf(file, " ***\n");
     687:             return (ERROR);
     688:         }
     689:         fprintf(file, " %s", name2);
     690:         break;
     691:
     692:         case T_TXT:
     693:         {
     694:             char *cp2 = cp + dlen;
     695:             int c;
     696:
     697:             (void) fputs(" \"", file);
     698:             while (cp < cp2) {
     699:                 if (n = (unsigned char) *cp++) {
     700:                     for (c = n; c > 0 && cp < cp2; c--)
     701:                         if (*cp == '\n') {
     702:                         (void) putc('\\', file);
     703:                         (void) putc(*cp++, file);
     704:                         } else
     705:                         (void) putc(*cp++, file);
     706:                 }
     707:             }
     708:             (void) putc('"', file);
     709:         }
     710:         break;
     711:
     712:         case T_MINFO:
     713:         (void) putc(' ', file);
     714:         cp = Print_cdname(cp, msg, eom, file);
     715:         fprintf(file, "  ");
     716:         cp = Print_cdname(cp, msg, eom, file);
     717:         break;
     718:
     719:         case T_UINFO:
     720:         fprintf(file, " %s", cp);
     721:         break;
     722:
     723:         case T_UID:
     724:         case T_GID:
     725:         fprintf(file, " %lu", _getlong(cp));
     726:         break;
     727:
     728:         case T_WKS:
     729:         if (class == C_IN) {
     730:             struct protoent *pp;
     731:             struct servent *ss;
     732:             u_short port;
     733:
     734:             cp += 4;    /* skip inet address */
     735:             dlen -= 4;
     736:
     737:             setprotoent(1);
     738:             setservent(1);
     739:             n = *cp & 0377;
     740:             pp = getprotobynumber(n);
     741:             if (pp == 0)
     742:             fprintf(file," %-3d ", n);
     743:             else
     744:             fprintf(file," %-3s ", pp->p_name);
     745:             cp++; dlen--;
     746:
     747:             port = 0;
     748:             while (dlen-- > 0) {
     749:             n = *cp++;
     750:             do {
     751:                 if (n & 0200) {
     752:                 ss = getservbyport((int)htons(port),
     753:                         pp->p_name);
     754:                 if (ss == 0)
     755:                     fprintf(file," %u", port);
     756:                 else
     757:                     fprintf(file," %s", ss->s_name);
     758:                 }
     759:                 n <<= 1;
     760:             } while (++port & 07);
     761:             }
     762:             endprotoent();
     763:             endservent();
     764:         }
     765:         break;
     766:     }
     767:     fprintf(file,"\n");
     768:     }
     769:     return(SUCCESS);
     770: }
     771:
     772:
     773: /*
     774:  *******************************************************************************
     775:  *
     776:  *  ViewList --
     777:  *
     778:  *	A hack to view the output of the ls command in sorted
     779:  *	order using more.
     780:  *
     781:  *******************************************************************************
     782:  */
     783:
     784: ViewList(string)
     785:     char *string;
     786: {
     787:     char file[NAME_LEN];
     788:     char command[NAME_LEN];
     789:
     790:     sscanf(string, " view %s", file);
     791:     (void)sprintf(command, "grep \"^ \" %s | sort | more", file);
     792:     system(command);
     793: }
     794:
     795: /*
     796:  *******************************************************************************
     797:  *
     798:  *   Finger --
     799:  *
     800:  *	Connects with the finger server for the current host
     801:  *	to request info on the specified person (long form)
     802:  *	who is on the system (short form).
     803:  *
     804:  *  Results:
     805:  *	SUCCESS		the finger server was contacted.
     806:  *	ERROR		the server could not be contacted because
     807:  *			a socket could not be obtained or connected
     808:  *			to or the service could not be found.
     809:  *
     810:  *******************************************************************************
     811:  */
     812:
     813: Finger(string, putToFile)
     814:     char *string;
     815:     int  putToFile;
     816: {
     817:     struct servent      *sp;
     818:     struct sockaddr_in  sin;
     819:     register FILE       *f;
     820:     register int        c;
     821:     register int        lastc;
     822:     char            name[NAME_LEN];
     823:     char            file[NAME_LEN];
     824:
     825:     /*
     826: 	 *  We need a valid current host info to get an inet address.
     827: 	 */
     828:     if (!curHostValid) {
     829:         fprintf(stderr, "Finger: no current host defined.\n");
     830:         return (ERROR);
     831:     }
     832:
     833:     if (sscanf(string, " finger %s", name) == 1) {
     834:         if (putToFile && (name[0] == '>')) {
     835:         name[0] = '\0';
     836:         }
     837:     } else {
     838:         name[0] = '\0';
     839:     }
     840:
     841:     sp = getservbyname("finger", "tcp");
     842:     if (sp == 0) {
     843:         fprintf(stderr, "Finger: unknown service\n");
     844:         return (ERROR);
     845:     }
     846:
     847:     bzero((char *)&sin, sizeof(sin));
     848:     sin.sin_family  = curHostInfo.addrType;
     849:     sin.sin_port    = sp->s_port;
     850:     bcopy(curHostInfo.addrList[0], (char *)&sin.sin_addr,
     851:         curHostInfo.addrLen);
     852:
     853:     /*
     854: 	 *  Set up a virtual circuit to the host.
     855: 	 */
     856:
     857:     sockFD = socket(curHostInfo.addrType, SOCK_STREAM, 0);
     858:     if (sockFD < 0) {
     859:         fflush(stdout);
     860:         perror("finger: socket");
     861:         return (ERROR);
     862:     }
     863:
     864:     if (connect(sockFD, (char *)&sin, sizeof (sin)) < 0) {
     865:         fflush(stdout);
     866:         perror("finger: connect");
     867:         close(sockFD);
     868:         sockFD = -1;
     869:         return (ERROR);
     870:     }
     871:
     872:     if (!putToFile) {
     873:         filePtr = stdout;
     874:     } else {
     875:         filePtr = OpenFile(string, file);
     876:         if (filePtr == NULL) {
     877:         fprintf(stderr, "*** Can't open %s for writing\n", file);
     878:         close(sockFD);
     879:         sockFD = -1;
     880:         return(ERROR);
     881:         }
     882:         fprintf(filePtr,"> %s\n", string);
     883:     }
     884:     fprintf(filePtr, "[%s]\n", curHostInfo.name);
     885:
     886:     if (name[0] != '\0') {
     887:         write(sockFD, "/W ", 3);
     888:     }
     889:     write(sockFD, name, strlen(name));
     890:     write(sockFD, "\r\n", 2);
     891:     f = fdopen(sockFD, "r");
     892:     while ((c = getc(f)) != EOF) {
     893:         switch (c) {
     894:         case 0210:
     895:         case 0211:
     896:         case 0212:
     897:         case 0214:
     898:             c -= 0200;
     899:             break;
     900:         case 0215:
     901:             c = '\n';
     902:             break;
     903:         }
     904:         putc(lastc = c, filePtr);
     905:     }
     906:     if (lastc != '\n') {
     907:         putc('\n', filePtr);
     908:     }
     909:     putc('\n', filePtr);
     910:
     911:     close(sockFD);
     912:     sockFD = -1;
     913:
     914:     if (putToFile) {
     915:         fclose(filePtr);
     916:         filePtr = NULL;
     917:     }
     918:     return (SUCCESS);
     919: }
     920:
     921: ListHost_close()
     922: {
     923:     if (sockFD != -1) {
     924:     (void) close(sockFD);
     925:     sockFD = -1;
     926:     }
     927: }

#### Defined functions

Finger defined in line 813; never used
ListHost_close defined in line 921; used 1 times

- in /usr/src/usr.sbin/named/tools/nslookup/subr.c line 92

ListHosts defined in line 147; never used
ListHostsByType defined in line 110; never used
ListSubr defined in line 193; used 3 times

- in line 68, 141, 187

PrintListInfo defined in line 524; used 1 times

- in line 419

ViewList defined in line 784; never used
strip_domain defined in line 505; used 1 times

- in line 589

#### Defined variables

sccsid defined in line 21; never used
sockFD defined in line 67; used 30 times

- in line 254-258(2), 266-267(2), 277-281(4), 295-296(2), 379, 410, 453-454(2), 857-858(2), 864-868(3), 878-879(2), 887-891(4), 911-912(2), 923-925(3)

#### Defined macros

HASH_SIZE defined in line 75; used 2 times

- in line 426, 448

NAME_FORMAT defined in line 503; used 1 times

- in line 596

Last modified: 1993-04-26 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2142 |