Annotation of 43BSDReno/usr.sbin/named/tools/nslookup/list.c, revision 1.1.1.1

1.1       root        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: #ifndef lint
                     21: static char sccsid[] = "@(#)list.c     5.20 (Berkeley) 6/1/90";
                     22: #endif /* not lint */
                     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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.