Annotation of 43BSD/etc/named/tools/ns.lookup/src/list.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *******************************************************************************
        !             3:  *
        !             4:  *  list.c --
        !             5:  *
        !             6:  *     Routines to obtain info from name and finger servers.
        !             7:  *
        !             8:  *     Adapted from 4.3BSD BIND ns_init.c and from /usr/src/ucb/finger.c
        !             9:  *
        !            10:  *     Copyright (c) 1985 Regents of the University of California.
        !            11:  *     All rights reserved.  The Berkeley software License Agreement
        !            12:  *     specifies the terms and conditions for redistribution.
        !            13:  *
        !            14:  *******************************************************************************
        !            15:  */
        !            16: 
        !            17: #ifndef lint
        !            18: static char sccsid[] = "@(#)list.c     5.4 (Berkeley) 4/10/86";
        !            19: #endif not lint
        !            20: 
        !            21: #include <sys/types.h>
        !            22: #include <sys/socket.h>
        !            23: #include <netinet/in.h>
        !            24: #include <netdb.h>
        !            25: #include <stdio.h>
        !            26: #include <strings.h>
        !            27: #include <ctype.h>
        !            28: #include <arpa/nameser.h>
        !            29: #include <resolv.h>
        !            30: #include "res.h"
        !            31: 
        !            32: /*
        !            33:  *  Imported from res_debug.c
        !            34:  */
        !            35: extern char *rcodes[];
        !            36: 
        !            37: typedef union {
        !            38:     HEADER qb1;
        !            39:     char qb2[PACKETSZ];
        !            40: } querybuf;
        !            41: 
        !            42: extern u_long          inet_addr();
        !            43: extern HostInfo        *defaultPtr;
        !            44: extern HostInfo        curHostInfo;
        !            45: extern int             curHostValid;
        !            46: 
        !            47: /*
        !            48:  *  During a listing to a file, hash marks are printed 
        !            49:  *  every HASH_SIZE records.
        !            50:  */
        !            51: 
        !            52: #define HASH_SIZE 50
        !            53: 
        !            54: 
        !            55: /*
        !            56:  *******************************************************************************
        !            57:  *
        !            58:  *  ListHosts --
        !            59:  *
        !            60:  *     Requests the name server to do a zone transfer so we
        !            61:  *     find out what hosts it knows about.
        !            62:  *
        !            63:  *     There are three types of output:
        !            64:  *     - internet addresses (default)
        !            65:  *     - cpu type and operating system (-h option)
        !            66:  *     - canonical and alias names  (-a option)
        !            67:  *     
        !            68:  *     To see all three types of information in sorted order, 
        !            69:  *     do the following:
        !            70:  *       ls domain.edu > file
        !            71:  *       ls -a domain.edu >> file
        !            72:  *       ls -h domain.edu >> file
        !            73:  *       view file
        !            74:  *
        !            75:  *  Results:
        !            76:  *     SUCCESS         the listing was successful.
        !            77:  *     ERROR           the server could not be contacted because 
        !            78:  *                     a socket could not be obtained or an error
        !            79:  *                     occured while receiving, or the output file
        !            80:  *                     could not be opened.
        !            81:  *
        !            82:  *******************************************************************************
        !            83:  */
        !            84: 
        !            85: int
        !            86: ListHosts(string, putToFile)
        !            87:     char *string;
        !            88:     int  putToFile;
        !            89: {
        !            90:        querybuf                buf;
        !            91:        struct sockaddr_in      sin;
        !            92:        HEADER                  *headerPtr;
        !            93:        int                     queryType;
        !            94:        int                     msglen;
        !            95:        int                     amtToRead;
        !            96:        int                     numRead;
        !            97:        int                     i;
        !            98:        int                     numAnswers = 0;
        !            99:        int                     result;
        !           100:        int                     soacnt = 0;
        !           101:        u_short                 len;
        !           102:        char                    *cp;
        !           103:        char                    name[NAME_LEN];
        !           104:        char                    option[NAME_LEN];
        !           105:        char                    file[NAME_LEN];
        !           106:        char                    *namePtr;
        !           107:        enum {
        !           108:            NO_ERRORS, 
        !           109:            ERR_READING_LEN, 
        !           110:            ERR_READING_MSG,
        !           111:            ERR_PRINTING,
        !           112:        } error = NO_ERRORS;
        !           113: 
        !           114: 
        !           115:        /*
        !           116:         *
        !           117:     /*
        !           118:      *  Parse the command line. It maybe of the form "ls domain",
        !           119:      *  "ls -a domain" or "ls -h domain".
        !           120:      */ 
        !           121:        i = sscanf(string, " ls %s %s", option, name);
        !           122:        if (putToFile && i == 2 && name[0] == '>') {
        !           123:            i--;
        !           124:        }
        !           125:        if (i == 2) {
        !           126:            if (strcmp("-a", option) == 0) {
        !           127:                queryType = T_CNAME;
        !           128:            } else if (strcmp("-h", option) == 0) {
        !           129:                queryType = T_HINFO;
        !           130:            } else if (strcmp("-m", option) == 0) {
        !           131:                queryType = T_MX;
        !           132:            } else {
        !           133:                queryType = T_A;
        !           134:            }
        !           135:            namePtr = name;
        !           136:        } else if (i == 1) {
        !           137:            namePtr = option;
        !           138:            queryType = T_A;
        !           139:        } else {
        !           140:            fprintf(stderr, "ListHosts: invalid request %s\n",string);
        !           141:            return(ERROR);
        !           142:        }
        !           143: 
        !           144: 
        !           145:        /*
        !           146:         *  Create a query packet for the requested domain name.
        !           147:         *
        !           148:         */
        !           149:        msglen = res_mkquery(QUERY, namePtr, C_IN, T_AXFR,
        !           150:                                (char *)0, 0, (char *)0, 
        !           151:                                (char *) &buf, sizeof(buf));
        !           152:        if (msglen < 0) {
        !           153:            if (_res.options & RES_DEBUG) {
        !           154:                fprintf(stderr, "ListHosts: Res_mkquery failed\n");
        !           155:            }
        !           156:            return (ERROR);
        !           157:        }
        !           158: 
        !           159:        bzero((char *)&sin, sizeof(sin));
        !           160:        sin.sin_family  = AF_INET;
        !           161:        sin.sin_port    =  htons(NAMESERVER_PORT);
        !           162: 
        !           163:        /*
        !           164:         *  Check to see if we have the address of the server or the
        !           165:         *  address of a server who knows about this domain.
        !           166:         *       
        !           167:         *  For now, just use the first address in the list.
        !           168:         */
        !           169: 
        !           170:        if (defaultPtr->addrList != NULL) {
        !           171:          sin.sin_addr = *(struct in_addr *) defaultPtr->addrList[0];
        !           172:        } else {
        !           173:          sin.sin_addr = *(struct in_addr *)defaultPtr->servers[0]->addrList[0];
        !           174:        }
        !           175: 
        !           176:        /*
        !           177:         *  Set up a virtual circuit to the server.
        !           178:         */
        !           179:        if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        !           180:            perror("ListHosts");
        !           181:            return(ERROR);
        !           182:        }       
        !           183:        if (connect(sockFD, &sin, sizeof(sin)) < 0) {
        !           184:            perror("ListHosts");
        !           185:            (void) close(sockFD);
        !           186:            sockFD = -1;
        !           187:            return(ERROR);
        !           188:        }       
        !           189: 
        !           190:        /*
        !           191:         * Send length & message for zone transfer 
        !           192:         */
        !           193: 
        !           194:         len = htons(msglen);
        !           195: 
        !           196:         if (write(sockFD, (char *)&len, sizeof(len)) != sizeof(len) ||
        !           197:             write(sockFD, (char *) &buf, msglen) != msglen) {
        !           198:                perror("ListHosts");
        !           199:                (void) close(sockFD);
        !           200:                sockFD = -1;
        !           201:                return(ERROR);
        !           202:        }
        !           203: 
        !           204:        fprintf(stdout,"[%s]\n",
        !           205:                (defaultPtr->addrList != NULL) ? defaultPtr->name : 
        !           206:                 defaultPtr->servers[0]->name);
        !           207: 
        !           208:        if (!putToFile) {
        !           209:            filePtr = stdout;
        !           210:        } else {
        !           211:            filePtr = OpenFile(string, file);
        !           212:             if (filePtr == NULL) {
        !           213:                 fprintf(stderr, "*** Can't open %s for writing\n", file);
        !           214:                (void) close(sockFD);
        !           215:                sockFD = -1;
        !           216:                 return(ERROR);
        !           217:             }
        !           218:            fprintf(filePtr, "> %s\n", string);
        !           219:            fprintf(filePtr,"[%s]\n",
        !           220:                (defaultPtr->addrList != NULL) ? defaultPtr->name : 
        !           221:                 defaultPtr->servers[0]->name);
        !           222:        }
        !           223: 
        !           224:        fprintf(filePtr, "%-30s", "Host or domain name");
        !           225:        switch(queryType) {
        !           226:            case T_A:
        !           227:                    fprintf(filePtr, " %-30s\n", "Internet address");
        !           228:                    break;
        !           229:            case T_HINFO:
        !           230:                    fprintf(filePtr, " %-20s %s\n", "CPU", "OS");
        !           231:                    break;
        !           232:            case T_CNAME:
        !           233:                    fprintf(filePtr, " %-30s\n", "Alias");
        !           234:                    break;
        !           235:            case T_MX:
        !           236:                    fprintf(filePtr, " %10s %s\n", "Metric", "Host");
        !           237:        }
        !           238: 
        !           239: 
        !           240:        while (1) {
        !           241: 
        !           242:            /*
        !           243:             * Read the length of the response.
        !           244:             */
        !           245: 
        !           246:            cp = (char *) &buf;
        !           247:            amtToRead = sizeof(u_short);
        !           248:            while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){
        !           249:                cp        += numRead;
        !           250:                amtToRead -= numRead;
        !           251:            }
        !           252:            if (numRead <= 0) {
        !           253:                error = ERR_READING_LEN;
        !           254:                break;
        !           255:            }   
        !           256: 
        !           257:            if ((len = htons(*(u_short *)&buf)) == 0) {
        !           258:                break;  /* nothing left to read */
        !           259:            }
        !           260: 
        !           261:            /*
        !           262:             * Read the response.
        !           263:             */
        !           264: 
        !           265:            amtToRead = len;
        !           266:            cp = (char *) &buf;
        !           267:            while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){
        !           268:                cp += numRead;
        !           269:                amtToRead -= numRead;
        !           270:            }
        !           271:            if (numRead <= 0) {
        !           272:                error = ERR_READING_MSG;
        !           273:                break;
        !           274:            }
        !           275: 
        !           276:            result = PrintListInfo(filePtr, (char *) &buf, cp, queryType);
        !           277:            if (result != SUCCESS) {
        !           278:                error = ERR_PRINTING;
        !           279:                break;
        !           280:            }
        !           281: 
        !           282:            numAnswers++;
        !           283:            if (putToFile && ((numAnswers % HASH_SIZE) == 0)) {
        !           284:                fprintf(stdout, "#");
        !           285:                fflush(stdout);
        !           286:            }
        !           287:            cp = buf.qb2 + sizeof(HEADER);
        !           288:            cp += dn_skip(cp) + QFIXEDSZ;
        !           289:            cp += dn_skip(cp);
        !           290:            if ((getshort(cp) == T_SOA)) {
        !           291:                if (soacnt)
        !           292:                    break;
        !           293:                else
        !           294:                    soacnt++;
        !           295:            }
        !           296:        }
        !           297: 
        !           298:        if (putToFile) {
        !           299:            fprintf(stdout, "%sReceived %d record%s.\n", 
        !           300:                (numAnswers >= HASH_SIZE) ? "\n" : "",
        !           301:                numAnswers,
        !           302:                (numAnswers > 1) ? "s" : "");
        !           303:        }
        !           304: 
        !           305:        (void) close(sockFD);
        !           306:        sockFD = -1;
        !           307:        if (putToFile) {
        !           308:            fclose(filePtr);
        !           309:            filePtr = NULL;
        !           310:        }
        !           311: 
        !           312:        switch (error) {
        !           313:            case NO_ERRORS:
        !           314:                return (SUCCESS);
        !           315: 
        !           316:            case ERR_READING_LEN:
        !           317:                return(ERROR);
        !           318: 
        !           319:            case ERR_PRINTING:
        !           320:                fprintf(stderr,"*** Error during listing of %s: %s\n", 
        !           321:                                namePtr, DecodeError(result));
        !           322:                return(result);
        !           323: 
        !           324:            case ERR_READING_MSG:
        !           325:                headerPtr = (HEADER *) &buf;
        !           326:                fprintf(stderr,"ListHosts: error receiving zone transfer:\n");
        !           327:                fprintf(stderr,
        !           328:               "  result: %s, answers = %d, authority = %d, additional = %d\n", 
        !           329:                        rcodes[headerPtr->rcode], 
        !           330:                        ntohs(headerPtr->ancount), ntohs(headerPtr->nscount), 
        !           331:                        ntohs(headerPtr->arcount));
        !           332:                return(ERROR);
        !           333:            default:
        !           334:                return(ERROR);
        !           335:        }
        !           336: }
        !           337: 
        !           338: 
        !           339: /*
        !           340:  *******************************************************************************
        !           341:  *
        !           342:  *  PrintListInfo --
        !           343:  *
        !           344:  *     Used by the ListInfo routine to print the answer 
        !           345:  *     received from the name server. Only the desired 
        !           346:  *     information is printed.
        !           347:  *
        !           348:  *  Results:
        !           349:  *     SUCCESS         the answer was printed without a problem.
        !           350:  *     NO_INFO         the answer packet did not contain an answer.
        !           351:  *     ERROR           the answer was malformed.
        !           352:  *      Misc. errors   returned in the packet header.
        !           353:  *
        !           354:  *******************************************************************************
        !           355:  */
        !           356: 
        !           357: #define NAME_FORMAT " %-30s"
        !           358: #define STRIP_DOMAIN(string) if((dot = index(string, '.')) != NULL) *dot = '\0'
        !           359: 
        !           360: 
        !           361: PrintListInfo(file, msg, eom, queryType)
        !           362:     FILE       *file;
        !           363:     char       *msg, *eom;
        !           364:     int        queryType;
        !           365: {
        !           366:     register char      *cp;
        !           367:     HEADER             *headerPtr;
        !           368:     int                type, class, dlen, nameLen;
        !           369:     int                n;
        !           370:     struct in_addr     inaddr;
        !           371:     char               name[NAME_LEN];
        !           372:     char               name2[NAME_LEN];
        !           373:     char               *dot;
        !           374: 
        !           375:     /*
        !           376:      * Read the header fields.
        !           377:      */
        !           378:     headerPtr = (HEADER *)msg;
        !           379:     cp = msg + sizeof(HEADER);
        !           380:     if (headerPtr->rcode != NOERROR) {
        !           381:        return(headerPtr->rcode);
        !           382:     }
        !           383: 
        !           384:     /*
        !           385:      *  We are looking for info from answer resource records.
        !           386:      *  If there aren't any, return with an error. We assume
        !           387:      *  there aren't any question records.
        !           388:      */
        !           389: 
        !           390:     if (ntohs(headerPtr->ancount) == 0) {
        !           391:        return(NO_INFO);
        !           392:     } else {
        !           393:        if ((nameLen = dn_expand(msg, eom, cp, name, sizeof(name))) < 0) {
        !           394:            return (ERROR);
        !           395:        }
        !           396:        cp += nameLen;
        !           397:        type = getshort(cp);
        !           398:        cp += sizeof(u_short);
        !           399:        class = getshort(cp);
        !           400:        cp += sizeof(u_short) + sizeof(u_long);
        !           401:        dlen = getshort(cp);
        !           402:        cp += sizeof(u_short);
        !           403: 
        !           404:        /*
        !           405:         * QueryType is used to specify the type of desired information.
        !           406:         *  T_A         - internet address
        !           407:         *  T_CNAME     - aliases
        !           408:         *  T_HINFO     - cpu, OS type
        !           409:         *  T_MX        - mail routing
        !           410:         *
        !           411: 
        !           412:         */
        !           413:        switch (type) {
        !           414: 
        !           415:            case T_A:
        !           416:                if (queryType != T_A)
        !           417:                    break;
        !           418: 
        !           419:                if (class == C_IN) {
        !           420:                    STRIP_DOMAIN(name);
        !           421:                    fprintf(file, NAME_FORMAT, name);
        !           422:                    bcopy(cp, (char *)&inaddr, sizeof(inaddr));
        !           423:                    if (dlen == 4) {
        !           424:                        fprintf(file," %s\n", inet_ntoa(inaddr));
        !           425:                    } else if (dlen == 7) {
        !           426:                        fprintf(file," %s", inet_ntoa(inaddr));
        !           427:                        fprintf(file," (%d, %d)\n", cp[4],(cp[5] << 8) + cp[6]);
        !           428:                    }
        !           429:                }
        !           430:                break;
        !           431:                
        !           432:            case T_CNAME:
        !           433:                if (queryType != T_CNAME)
        !           434:                    break;
        !           435: 
        !           436:                STRIP_DOMAIN(name);
        !           437:                if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
        !           438:                    return (ERROR);
        !           439:                }
        !           440:                /* 
        !           441:                 * a bug -- cnames need not be in same domain!
        !           442:                 * STRIP_DOMAIN(name2);
        !           443:                 */
        !           444: 
        !           445:                fprintf(file, NAME_FORMAT, name2);
        !           446:                fprintf(file, " %s\n", name);
        !           447:                break;
        !           448:                
        !           449:            case T_HINFO:
        !           450:                if (queryType != T_HINFO)
        !           451:                    break;
        !           452: 
        !           453:                STRIP_DOMAIN(name);
        !           454:                fprintf(file, NAME_FORMAT, name);
        !           455:                if (n = *cp++) {
        !           456:                    sprintf(name,"%.*s", n, cp);
        !           457:                    fprintf(file," %-20s", name);
        !           458:                    cp += n;
        !           459:                } else {
        !           460:                    fprintf(file," %-20s", " ");
        !           461:                }
        !           462:                if (n = *cp++) {
        !           463:                    fprintf(file," %.*s\n", n, cp);
        !           464:                    cp += n;
        !           465:                }
        !           466:                break;
        !           467: 
        !           468:            case T_MX:
        !           469:                if (queryType != T_MX)
        !           470:                    break;
        !           471: 
        !           472:                STRIP_DOMAIN(name);
        !           473:                fprintf(file, NAME_FORMAT, name);
        !           474: 
        !           475:                {
        !           476:                    short pref;
        !           477: 
        !           478:                    pref = getshort(cp);
        !           479:                    cp += sizeof(u_short);
        !           480:                    fprintf(file,"%10d",pref);
        !           481:                }
        !           482:                if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
        !           483:                    return (ERROR);
        !           484:                }
        !           485:                fprintf(file, " %s\n", name2);
        !           486: 
        !           487:                break;
        !           488: 
        !           489: 
        !           490:            case T_NS:
        !           491:            case T_PTR:
        !           492:                if (queryType != T_A)
        !           493:                    break;
        !           494:                /*
        !           495:                 *  Found a name server or pointer record.
        !           496:                 */
        !           497:                fprintf(file, NAME_FORMAT, name);
        !           498:                fprintf(file," server = ");
        !           499:                cp = Print_cdname2(cp, msg, eom, file);
        !           500:                fprintf(file,"\n");
        !           501:                break;
        !           502: 
        !           503:            default:
        !           504:                /*
        !           505:                 * Unwanted answer type -- ignore it.
        !           506:                 */
        !           507:                 break;
        !           508:        }
        !           509:     }
        !           510:     return(SUCCESS);
        !           511: }
        !           512: 
        !           513: 
        !           514: /*
        !           515:  *******************************************************************************
        !           516:  *
        !           517:  *  ViewList --
        !           518:  *
        !           519:  *     A hack to view the output of the ls command in sorted
        !           520:  *     order using more.
        !           521:  *
        !           522:  *******************************************************************************
        !           523:  */
        !           524: 
        !           525: ViewList(string)
        !           526:     char *string;
        !           527: {
        !           528:     char file[NAME_LEN];
        !           529:     char command[NAME_LEN];
        !           530: 
        !           531:     sscanf(string, " view %s", file);
        !           532:     sprintf(command, "grep \"^ \" %s | sort | more", file);
        !           533:     system(command);
        !           534: }
        !           535: 
        !           536: /*
        !           537:  *******************************************************************************
        !           538:  *
        !           539:  *   Finger --
        !           540:  *
        !           541:  *     Connects with the finger server for the current host
        !           542:  *     to request info on the specified person (long form)
        !           543:  *     who is on the system (short form).
        !           544:  *
        !           545:  *  Results:
        !           546:  *     SUCCESS         the finger server was contacted.
        !           547:  *     ERROR           the server could not be contacted because 
        !           548:  *                     a socket could not be obtained or connected 
        !           549:  *                     to or the service could not be found.
        !           550:  *
        !           551:  *******************************************************************************
        !           552:  */
        !           553: 
        !           554: Finger(string, putToFile)
        !           555:     char *string;
        !           556:     int  putToFile;
        !           557: {
        !           558:        struct servent          *sp;
        !           559:        struct sockaddr_in      sin;
        !           560:        register FILE           *f;
        !           561:        register int            c;
        !           562:        register int            lastc;
        !           563:        char                    name[NAME_LEN];
        !           564:        char                    file[NAME_LEN];
        !           565: 
        !           566:        /*
        !           567:         *  We need a valid current host info to get an inet address.
        !           568:         */
        !           569:        if (!curHostValid) {
        !           570:            fprintf(stderr, "Finger: no current host defined.\n");
        !           571:            return (ERROR);
        !           572:        }
        !           573: 
        !           574:        if (sscanf(string, " finger %s", name) == 1) {
        !           575:            if (putToFile && (name[0] == '>')) {
        !           576:                name[0] = '\0';
        !           577:            }
        !           578:        } else {
        !           579:            name[0] = '\0';
        !           580:        }
        !           581: 
        !           582:        sp = getservbyname("finger", "tcp");
        !           583:        if (sp == 0) {
        !           584:            fprintf(stderr, "Finger: unknown service\n");
        !           585:            return (ERROR);
        !           586:        }
        !           587: 
        !           588:        bzero((char *)&sin, sizeof(sin));
        !           589:        sin.sin_family  = curHostInfo.addrType;
        !           590:        sin.sin_port    = sp->s_port;
        !           591:        bcopy(curHostInfo.addrList[0], (char *)&sin.sin_addr, 
        !           592:                curHostInfo.addrLen);
        !           593: 
        !           594:        /*
        !           595:         *  Set up a virtual circuit to the host.
        !           596:         */
        !           597: 
        !           598:        sockFD = socket(curHostInfo.addrType, SOCK_STREAM, 0);
        !           599:        if (sockFD < 0) {
        !           600:            fflush(stdout);
        !           601:            perror("Finger");
        !           602:            return (ERROR);
        !           603:        }
        !           604: 
        !           605:        if (connect(sockFD, (char *)&sin, sizeof (sin)) < 0) {
        !           606:            fflush(stdout);
        !           607:            perror("Finger");
        !           608:            close(sockFD);
        !           609:            sockFD = -1;
        !           610:            return (ERROR);
        !           611:        }
        !           612: 
        !           613:        if (!putToFile) {
        !           614:            filePtr = stdout;
        !           615:        } else {
        !           616:            filePtr = OpenFile(string, file);
        !           617:            if (filePtr == NULL) {
        !           618:                fprintf(stderr, "*** Can't open %s for writing\n", file);
        !           619:                close(sockFD);
        !           620:                sockFD = -1;
        !           621:                return(ERROR);
        !           622:            }
        !           623:            fprintf(filePtr,"> %s\n", string);
        !           624:        }
        !           625:        fprintf(filePtr, "[%s]\n", curHostInfo.name);
        !           626: 
        !           627:        if (name[0] != '\0') {
        !           628:            write(sockFD, "/W ", 3);
        !           629:        }
        !           630:        write(sockFD, name, strlen(name));
        !           631:        write(sockFD, "\r\n", 2);
        !           632:        f = fdopen(sockFD, "r");
        !           633:        while ((c = getc(f)) != EOF) {
        !           634:            switch(c) {
        !           635:                case 0210:
        !           636:                case 0211:
        !           637:                case 0212:
        !           638:                case 0214:
        !           639:                        c -= 0200;
        !           640:                        break;
        !           641:                case 0215:
        !           642:                        c = '\n';
        !           643:                        break;
        !           644:            }
        !           645:            putc(lastc = c, filePtr);
        !           646:        }
        !           647:        if (lastc != '\n') {
        !           648:            putc('\n', filePtr);
        !           649:        }
        !           650:        putc('\n', filePtr);
        !           651: 
        !           652:        close(sockFD);
        !           653:        sockFD = -1;
        !           654: 
        !           655:        if (putToFile) {
        !           656:            fclose(filePtr);
        !           657:            filePtr = NULL;
        !           658:        }
        !           659:        return (SUCCESS);
        !           660: }

unix.superglobalmegacorp.com

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